aboutsummaryrefslogtreecommitdiff
path: root/system/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'system/kernel')
-rw-r--r--system/kernel/CONTENTS7
-rw-r--r--system/kernel/Makefile16
-rw-r--r--system/kernel/pdp.c198
-rw-r--r--system/kernel/pdp_comm.c198
-rw-r--r--system/kernel/pdp_compat.c56
-rw-r--r--system/kernel/pdp_control.c186
-rw-r--r--system/kernel/pdp_debug.c21
-rw-r--r--system/kernel/pdp_dpd_command.c87
-rw-r--r--system/kernel/pdp_forth.c541
-rw-r--r--system/kernel/pdp_list.c663
-rw-r--r--system/kernel/pdp_mem.c129
-rw-r--r--system/kernel/pdp_packet.c957
-rw-r--r--system/kernel/pdp_packet2.c623
-rw-r--r--system/kernel/pdp_post.c48
-rw-r--r--system/kernel/pdp_queue.c347
-rw-r--r--system/kernel/pdp_symbol.c196
-rw-r--r--system/kernel/pdp_type.c501
-rw-r--r--system/kernel/pdp_type.c_old542
-rw-r--r--system/kernel/pdp_ut.c262
19 files changed, 0 insertions, 5578 deletions
diff --git a/system/kernel/CONTENTS b/system/kernel/CONTENTS
deleted file mode 100644
index c2f7c8c..0000000
--- a/system/kernel/CONTENTS
+++ /dev/null
@@ -1,7 +0,0 @@
-debug debug stuff
-forth the forth system
-list the list implementation
-mem memory allocation stuf
-packet the packet memory manager
-type the type handling and conversion system
-symbol symbol implementation, with namespaces for forth, types, classes, ...
diff --git a/system/kernel/Makefile b/system/kernel/Makefile
deleted file mode 100644
index f1d82a9..0000000
--- a/system/kernel/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-
-OBJECTS = pdp.o pdp_ut.o pdp_packet.o pdp_queue.o pdp_comm.o \
- pdp_control.o pdp_compat.o pdp_type.o pdp_dpd_command.o \
- pdp_list.o pdp_forth.o
-
-
-include ../../Makefile.config
-
-all: pdp_main_clean $(OBJECTS)
-
-pdp_main_clean:
- rm -f pdp.o
-
-clean:
- rm -f *~
- rm -f *.o
diff --git a/system/kernel/pdp.c b/system/kernel/pdp.c
deleted file mode 100644
index d71e655..0000000
--- a/system/kernel/pdp.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Pure Data Packet system implementation: setup code
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include "pdp_config.h"
-#include "pdp.h"
-#include <stdio.h>
-
-/* all symbols are C style */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* module setup declarations (all C-style) */
-
-/* pdp system / internal stuff */
-void pdp_list_setup(void);
-void pdp_sym_setup(void);
-void pdp_forth_setup(void);
-void pdp_type_setup(void);
-void pdp_packet_setup(void);
-void pdp_ut_setup(void);
-void pdp_queue_setup(void);
-void pdp_control_setup(void);
-void pdp_image_setup(void);
-void pdp_bitmap_setup(void);
-void pdp_matrix_setup(void);
-
-
-/* pdp modules */
-void pdp_xv_setup(void);
-void pdp_add_setup(void);
-void pdp_mul_setup(void);
-void pdp_mix_setup(void);
-void pdp_randmix_setup(void);
-void pdp_qt_setup(void);
-void pdp_v4l_setup(void);
-void pdp_reg_setup(void);
-void pdp_conv_setup(void);
-void pdp_bq_setup(void);
-void pdp_del_setup(void);
-void pdp_snap_setup(void);
-void pdp_trigger_setup(void);
-void pdp_route_setup(void);
-void pdp_noise_setup(void);
-void pdp_gain_setup(void);
-void pdp_chrot_setup(void);
-void pdp_scope_setup(void);
-void pdp_scale_setup(void);
-void pdp_zoom_setup(void);
-void pdp_scan_setup(void);
-void pdp_scanxy_setup(void);
-void pdp_sdl_setup(void);
-void pdp_cheby_setup(void);
-void pdp_grey2mask_setup(void);
-void pdp_constant_setup(void);
-void pdp_logic_setup(void);
-void pdp_glx_setup(void);
-void pdp_loop_setup(void);
-void pdp_description_setup(void);
-void pdp_convert_setup(void);
-void pdp_stateless_setup(void);
-void pdp_mat_mul_setup(void);
-void pdp_mat_lu_setup(void);
-void pdp_mat_vec_setup(void);
-void pdp_plasma_setup(void);
-void pdp_cog_setup(void);
-void pdp_histo_setup(void);
-void pdp_array_setup(void);
-
-/* hacks */
-void pdp_inspect_setup(void);
-void pdp_slice_cut_setup(void);
-void pdp_slice_glue_setup(void);
-
-/* testing */
-void pdp_dpd_test_setup(void);
-void pdp_forthproc_setup(void);
-
-
-
-/* library setup routine */
-void pdp_setup(void){
-
- /* babble */
- post ("PDP: pure data packet");
-
-#ifdef PDP_VERSION
- fprintf(stderr, "PDP: version " PDP_VERSION "\n");
-#endif
-
-
- /* setup pdp system */
- pdp_list_setup();
- pdp_type_setup();
- pdp_sym_setup();
- pdp_packet_setup();
- pdp_forth_setup();
- pdp_control_setup();
-
- pdp_image_setup();
- pdp_bitmap_setup();
- pdp_matrix_setup();
-
- pdp_queue_setup();
-
- /* setup utility toolkit */
- pdp_ut_setup();
-
- /* setup pdp modules*/
- pdp_add_setup();
- pdp_mul_setup();
- pdp_mix_setup();
- pdp_randmix_setup();
- pdp_reg_setup();
- pdp_conv_setup();
- pdp_bq_setup();
- pdp_del_setup();
- pdp_snap_setup();
- pdp_trigger_setup();
- pdp_route_setup();
- pdp_noise_setup();
- pdp_plasma_setup();
- pdp_gain_setup();
- pdp_chrot_setup();
- pdp_scope_setup();
- pdp_scale_setup();
- pdp_zoom_setup();
- pdp_scan_setup();
- pdp_scanxy_setup();
- pdp_cheby_setup();
- pdp_grey2mask_setup();
- pdp_constant_setup();
- pdp_logic_setup();
- pdp_loop_setup();
- pdp_description_setup();
- pdp_convert_setup();
- pdp_stateless_setup();
- pdp_mat_mul_setup();
- pdp_mat_lu_setup();
- pdp_mat_vec_setup();
- pdp_cog_setup();
- pdp_histo_setup();
- pdp_array_setup();
-
- /* experimental stuff */
- pdp_slice_cut_setup();
- pdp_slice_glue_setup();
- pdp_inspect_setup();
-
- /* testing */
- //pdp_dpd_test_setup();
- pdp_forthproc_setup();
-
- /* optional modules */
-
-#ifdef HAVE_PDP_QT
- pdp_qt_setup();
-#endif
-
-#ifdef HAVE_PDP_XV
- pdp_xv_setup();
-#endif
-
-#ifdef HAVE_PDP_SDL
- pdp_sdl_setup();
-#endif
-
-#ifdef HAVE_PDP_V4L
- pdp_v4l_setup();
-#endif
-
-#ifdef HAVE_PDP_GLX
- pdp_glx_setup();
-#endif
-
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_comm.c b/system/kernel/pdp_comm.c
deleted file mode 100644
index bcc0e3a..0000000
--- a/system/kernel/pdp_comm.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Pure Data Packet system implementation.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* this file contains misc communication (packet) methods for pd */
-
-
-#include "pdp.h"
-#include "pdp_internals.h"
-#include <stdio.h>
-
-/* all symbols are C style */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-t_symbol *_pdp_sym_pdp;
-t_symbol *_pdp_sym_rro;
-t_symbol *_pdp_sym_rrw;
-t_symbol *_pdp_sym_prc;
-t_symbol *_pdp_sym_dpd;
-t_symbol *_pdp_sym_ins;
-t_symbol *_pdp_sym_acc;
-
-t_symbol *pdp_sym_pdp() {return _pdp_sym_pdp;}
-t_symbol *pdp_sym_rro() {return _pdp_sym_rro;}
-t_symbol *pdp_sym_rrw() {return _pdp_sym_rrw;}
-t_symbol *pdp_sym_prc() {return _pdp_sym_prc;}
-t_symbol *pdp_sym_dpd() {return _pdp_sym_dpd;}
-t_symbol *pdp_sym_ins() {return _pdp_sym_ins;}
-t_symbol *pdp_sym_acc() {return _pdp_sym_acc;}
-
-/************** packet management and communication convenience functions ************/
-
-/* send a packet to an outlet */
-void outlet_pdp(t_outlet *out, int packetid)
-{
- t_atom atom[2];
-
- SETFLOAT(atom+1, (float)packetid);
-
- SETSYMBOL(atom+0, pdp_sym_rro());
- outlet_anything(out, pdp_sym_pdp(), 2, atom);
-
- SETSYMBOL(atom+0, pdp_sym_rrw());
- outlet_anything(out, pdp_sym_pdp(), 2, atom);
-
- SETSYMBOL(atom+0, pdp_sym_prc());
- outlet_anything(out, pdp_sym_pdp(), 2, atom);
-
-}
-
-/* send an accumulation packet to an outlet */
-void outlet_dpd(t_outlet *out, int packetid)
-{
- t_atom atom[2];
-
- SETFLOAT(atom+1, (float)packetid);
-
- SETSYMBOL(atom+0, pdp_sym_ins());
- outlet_anything(out, pdp_sym_dpd(), 2, atom);
-
- SETSYMBOL(atom+0, pdp_sym_acc());
- outlet_anything(out, pdp_sym_dpd(), 2, atom);
-
-}
-
-/* unregister a packet and send it to an outlet */
-void
-
-pdp_packet_pass_if_valid(t_outlet *outlet, int *packet_ptr)
-{
- t_pdp *header = pdp_packet_header(*packet_ptr);
- //if (-1 != *packet){
- if (header){
- /* if packet is exclusively owned, mark as passing */
- if (1 == header->users) pdp_packet_mark_passing(packet_ptr);
-
- /* send */
- outlet_pdp(outlet, *packet_ptr);
-
- /* if the packet is still here (was passing and not registered,
- or it was a shared copy): unregister it */
- if (-1 != *packet_ptr){
- pdp_packet_unmark_passing(*packet_ptr);
- pdp_packet_mark_unused(*packet_ptr);
- *packet_ptr = -1;
- }
- }
-}
-
-void
-pdp_packet_replace_if_valid(int *dpacket, int *spacket)
-{
- if (-1 != *spacket){
- pdp_packet_mark_unused(*dpacket);
- *dpacket = *spacket;
- *spacket = -1;
- }
-
-}
-
-
-int
-pdp_packet_copy_ro_or_drop(int *dpacket, int spacket)
-{
- int drop = 0;
- if (*dpacket == -1) *dpacket = pdp_packet_copy_ro(spacket);
- else {
- /* send a notification there is a dropped packet */
- pdp_control_notify_drop(spacket);
- drop = 1;
- }
- return drop;
-}
-
-
-int
-pdp_packet_copy_rw_or_drop(int *dpacket, int spacket)
-{
- int drop = 0;
- if (*dpacket == -1) *dpacket = pdp_packet_copy_rw(spacket);
- else {
- /* send a notification there is a dropped packet */
- pdp_control_notify_drop(spacket);
- drop = 1;
- }
- return drop;
-}
-
-int
-pdp_packet_convert_ro_or_drop(int *dpacket, int spacket, t_pdp_symbol *template)
-{
- int drop = 0;
-
- if (!template) return pdp_packet_copy_ro_or_drop(dpacket, spacket);
-
- if (*dpacket == -1) *dpacket = pdp_packet_convert_ro(spacket, template);
- else {
- /* send a notification there is a dropped packet */
- pdp_control_notify_drop(spacket);
- drop = 1;
- }
- return drop;
-}
-
-
-int
-pdp_packet_convert_rw_or_drop(int *dpacket, int spacket, t_pdp_symbol *template)
-{
- int drop = 0;
-
- if (!template) return pdp_packet_copy_rw_or_drop(dpacket, spacket);
-
- if (*dpacket == -1) *dpacket = pdp_packet_convert_rw(spacket, template);
- else {
- /* send a notification there is a dropped packet */
- pdp_control_notify_drop(spacket);
- drop = 1;
- }
- return drop;
-}
-
-
-void
-pdp_sym_setup(void)
-{
- _pdp_sym_pdp = gensym("pdp");
- _pdp_sym_rro = gensym("register_ro");
- _pdp_sym_rrw = gensym("register_rw");
- _pdp_sym_prc = gensym("process");
- _pdp_sym_dpd = gensym("dpd");
- _pdp_sym_ins = gensym("inspect");
- _pdp_sym_acc = gensym("accumulate");
-}
-
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_compat.c b/system/kernel/pdp_compat.c
deleted file mode 100644
index 4bcf00d..0000000
--- a/system/kernel/pdp_compat.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Pure Data Packet system implementation. Compatibility routines.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* this file contains misc communication methods */
-
-
-#include "pdp.h"
-#include "pdp_internals.h"
-#include <stdio.h>
-
-/* all symbols are C style */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-
-void
-pdp_pass_if_valid(t_outlet *outlet, int *packet)
-{
- pdp_packet_pass_if_valid(outlet, packet);
-}
-
-void
-pdp_replace_if_valid(int *dpacket, int *spacket)
-{
- pdp_packet_replace_if_valid(dpacket, spacket);
-
-}
-
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_control.c b/system/kernel/pdp_control.c
deleted file mode 100644
index 2cba7b7..0000000
--- a/system/kernel/pdp_control.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Pure Data Packet system implementation: control object
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-/* this is an actual pd class that is used for communication with the
- pdp framework */
-
-#include "pdp.h"
-#include "pdp_internals.h"
-#include "pdp_control.h"
-#include <stdio.h>
-
-/* all symbols are C style */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-
-static long dropped_packets;
-
-static t_class* pdp_control_class;
-
-
-/* pdp control instance data */
-
-struct _pdp_control;
-typedef struct _pdp_control
-{
- t_object x_obj;
- t_outlet *x_outlet0;
- struct _pdp_control *x_next;
-
-} t_pdp_control;
-
-
-
-static t_pdp_control *pdp_control_list;
-
-static void pdp_control_info(t_pdp_control *x)
-{
-}
-
-static void pdp_control_collectgarbage(t_pdp_control *x)
-{
- int nb_packets_freed = pdp_pool_collect_garbage();
- post("pdp_control: freed %d packets", nb_packets_freed);
-
-}
-
-static void pdp_control_set_mem_limit(t_pdp_control *x, t_floatarg f)
-{
- int limit = (int)f;
- if (limit < 0) limit = 0;
- pdp_pool_set_max_mem_usage(limit);
- if (limit) post("pdp_control: set memory limit to %d bytes", limit);
- else post("pdp_control: disabled memory limit");
-
-}
-
-static void pdp_control_thread(t_pdp_control *x, t_floatarg f)
-{
- int t = (int)f;
-
- if (t){
- post("pdp_control: pdp is now using its own processing thread");
- pdp_queue_use_thread(1);
- }
- else {
- post("pdp_control: pdp is now using the main pd thread");
- pdp_queue_use_thread(0);
- }
-}
-
-
-static void pdp_control_send_drop_message(t_pdp_control *x)
-{
- t_atom atom[1];
- t_symbol *s = gensym("pdp_drop");
-
- SETFLOAT(atom+0, (float)dropped_packets);
- outlet_anything(x->x_outlet0, s, 1, atom);
-}
-
-
-static void pdp_control_free(t_pdp_control *x)
-{
- /* remove from linked list */
- t_pdp_control *curr = pdp_control_list;
- if (pdp_control_list == x) pdp_control_list = x->x_next;
- else while (curr){
- if (curr->x_next == x) {
- curr->x_next = x->x_next;
- break;
- }
- else {
- curr = curr->x_next;
- }
-
- }
-}
-
-
-static void *pdp_control_new(void)
-{
- t_pdp_control *x = (t_pdp_control *)pd_new(pdp_control_class);
- x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
-
- /* add to list */
- x->x_next = pdp_control_list;
- pdp_control_list = x;
- return x;
-}
-
-/************************* class methods ***************************************/
-
-
-void pdp_control_addmethod(t_method m, t_symbol *s)
-{
- class_addmethod(pdp_control_class, m, s, A_GIMME, A_NULL);
-}
-
-void pdp_control_setup(void)
-{
-
- pdp_control_list = 0;
- dropped_packets = 0;
-
- /* setup pd class data */
- pdp_control_class = class_new(gensym("pdp_control"), (t_newmethod)pdp_control_new,
- (t_method)pdp_control_free, sizeof(t_pdp_control), 0, A_NULL);
-
-
- class_addmethod(pdp_control_class, (t_method)pdp_control_info, gensym("info"), A_NULL);
- class_addmethod(pdp_control_class, (t_method)pdp_control_thread, gensym("thread"), A_DEFFLOAT, A_NULL);
- class_addmethod(pdp_control_class, (t_method)pdp_control_collectgarbage, gensym("collectgarbage"), A_NULL);
- class_addmethod(pdp_control_class, (t_method)pdp_control_set_mem_limit, gensym("memlimit"), A_FLOAT, A_NULL);
-}
-
-
-
-void pdp_control_notify_broadcast(t_pdp_control_method_notify *notify)
-{
- t_pdp_control *curr = pdp_control_list;
- while (curr){
- (*notify)(curr);
- curr = curr->x_next;
- }
-}
-
-
-
-/************************* notify class methods *************************/
-
-void pdp_control_notify_drop(int packet)
-{
- dropped_packets++;
-
- /* send drop notify to controller class instances */
- pdp_control_notify_broadcast(pdp_control_send_drop_message);
- //post("dropped packet");
-}
-
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_debug.c b/system/kernel/pdp_debug.c
deleted file mode 100644
index 07f6541..0000000
--- a/system/kernel/pdp_debug.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-#include "pdp_post.h"
-
-int pdp_debug_sigtrap_on_assert;
-
-
-void pdp_assert_hook (char *condition, char *file, int line)
-{
- pdp_post("PDP_ASSERT (%s) failed in file %s, line %u. ", condition, file, line);
- pdp_post("%s.\n", pdp_debug_sigtrap_on_assert ? "sending SIGTRAP" : "continuing");
-
- if (pdp_debug_sigtrap_on_assert) kill(getpid(), SIGTRAP);
-}
-
-
-void pdp_debug_setup(void)
-{
- pdp_debug_sigtrap_on_assert = 1;
-}
diff --git a/system/kernel/pdp_dpd_command.c b/system/kernel/pdp_dpd_command.c
deleted file mode 100644
index 0d3ecf1..0000000
--- a/system/kernel/pdp_dpd_command.c
+++ /dev/null
@@ -1,87 +0,0 @@
-
-/*
- * Pure Data Packet header file. DPD command class
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* this object implements a dpd command queue and command object */
-
-#include "pdp.h"
-#include "pdp_dpd_command.h"
-
-void pdp_dpd_commandfactory_init(t_pdp_dpd_commandfactory *x, u32 size)
-{
- x->nb_commands = 0;
- x->command_size = size;
- x->command = 0;
-}
-
-void _pdp_dpd_commandfactory_free(t_pdp_dpd_command *x)
-{
- if (x) _pdp_dpd_commandfactory_free(x->next);
- pdp_dealloc(x);
-}
-
-void pdp_dpd_commandfactory_free(t_pdp_dpd_commandfactory *x)
-{
- _pdp_dpd_commandfactory_free(x->command);
- x->command = 0;
- x->nb_commands = 0;
-}
-
-
-/* factory method */
-t_pdp_dpd_command *pdp_dpd_commandfactory_get_new_command(t_pdp_dpd_commandfactory *x)
-{
-
- t_pdp_dpd_command *c = x->command;
- t_pdp_dpd_command *oldhead = c;
-
- /* check if we can reuse */
- while (c){
- if (!c->used){
- c->used = 1;
- //post("reusing command %x", c, c->used);
- return c;
- }
- //post("command %x is used %d", c, c->used);
- c = c->next;
- }
-
- /* create a new command */
- x->command = (t_pdp_dpd_command *)pdp_alloc(x->command_size);
- x->command->next = oldhead;
- x->command->used = 1;
- x->nb_commands++;
- //post("created command %x, nbcommands: %d", x->command, x->nb_commands);
- return x->command;
-
-}
-
-
-/* (self)destructor */
-void pdp_dpd_command_suicide(void *x)
-{
- t_pdp_dpd_command *c = (t_pdp_dpd_command *)x;
- c->used = 0;
- //post("command %x committed suicide %d", c, c->used);
-}
-
-
-
-
diff --git a/system/kernel/pdp_forth.c b/system/kernel/pdp_forth.c
deleted file mode 100644
index 1764004..0000000
--- a/system/kernel/pdp_forth.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Pure Data Packet header file. Packet processor system
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include "pdp.h"
-#include "pdp_forth.h"
-
-#define D if (0)
-
-
-
-t_pdp_stack *pdp_stack_new(void) {return pdp_list_new(0);}
-
-void pdp_stack_free(t_pdp_stack *s) {
- pdp_tree_strip_packets(s);
- pdp_list_free(s);
-}
-
-
-/* some stack manips */
-t_pdp_word_error pdp_stack_dup(t_pdp_stack *s)
-{
- if (!s->first) return e_underflow;
- pdp_list_add(s, s->first->t, s->first->w);
-
- /* copy it properly if its a packet */
- if (s->first->t == a_packet){
- s->first->w.w_packet = pdp_packet_copy_ro(s->first->w.w_packet);
- }
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_drop(t_pdp_stack *s)
-{
- if (!s->first) return e_underflow;
-
- /* delete it properly if its a packet */
- if (s->first->t == a_packet){
- pdp_packet_mark_unused(s->first->w.w_packet);
- }
- pdp_list_pop(s);
-
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_over(t_pdp_stack *s)
-{
- if (s->elements < 2) return e_underflow;
- pdp_list_add(s, s->first->next->t, s->first->next->w);
-
- /* copy it properly if its a packet */
- if (s->first->t == a_packet){
- s->first->w.w_packet = pdp_packet_copy_ro(s->first->w.w_packet);
- }
-
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_swap(t_pdp_stack *s)
-{
- t_pdp_word w;
- t_pdp_word_type t;
- if (s->elements < 2) return e_underflow;
- w = s->first->w;
- t = s->first->t;
- s->first->w = s->first->next->w;
- s->first->t = s->first->next->t;
- s->first->next->w = w;
- s->first->next->t = t;
- return e_ok;
-
-}
-
-/* pushing and popping the stack */
-
-t_pdp_word_error pdp_stack_push_float(t_pdp_stack *s, float f) {pdp_list_add(s, a_float, (t_pdp_word)f); return e_ok;}
-t_pdp_word_error pdp_stack_push_int(t_pdp_stack *s, int i) {pdp_list_add(s, a_int, (t_pdp_word)i); return e_ok;}
-t_pdp_word_error pdp_stack_push_pointer(t_pdp_stack *s, void *x) {pdp_list_add(s, a_pointer, (t_pdp_word)x); return e_ok;}
-t_pdp_word_error pdp_stack_push_symbol(t_pdp_stack *s, t_pdp_symbol *x) {pdp_list_add(s, a_symbol, (t_pdp_word)x); return e_ok;}
-
-/* note: packets pushed stack are owned by the stack. if a caller wants to keep a packet that
- will be deleted by the word, it should make a copy before transferring it to the stack.
- if a stack processor wants to write to a packet, it should replace it with a writable copy first */
-
-t_pdp_word_error pdp_stack_push_packet(t_pdp_stack *s, int p) {pdp_list_add(s, a_packet, (t_pdp_word)p); return e_ok;}
-
-
-
-
-
-t_pdp_word_error pdp_stack_pop_float(t_pdp_stack *s, float *f)
-{
- if (!s->first) return e_underflow;
-
- if (s->first->t == a_float) *f = s->first->w.w_float;
- else if (s->first->t == a_int) *f = (float)s->first->w.w_int;
- else *f = 0.0f;
- pdp_stack_drop(s);
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_pop_int(t_pdp_stack *s, int *i)
-{
- if (!s->first) return e_underflow;
- if (s->first->t == a_int) *i = s->first->w.w_int;
- else if (s->first->t == a_float) *i = (int)s->first->w.w_float;
- else *i = 0;
- pdp_stack_drop(s);
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_pop_pointer(t_pdp_stack *s, void **x)
-{
- if (!s->first) return e_underflow;
- *x = (s->first->t == a_pointer) ? s->first->w.w_pointer : 0;
- pdp_stack_drop(s);
- return e_ok;
-}
-
-t_pdp_word_error pdp_stack_pop_symbol(t_pdp_stack *s, t_pdp_symbol **x)
-{
- if (!s->first) return e_underflow;
- *x = (s->first->t == a_symbol) ? s->first->w.w_symbol : pdp_gensym("invalid");
- pdp_stack_drop(s);
- return e_ok;
-}
-
-/* packets popped from the stack are owned by the caller */
-
-t_pdp_word_error pdp_stack_pop_packet(t_pdp_stack *s, int *p)
-{
- if (!s->first) return e_underflow;
- *p = (s->first->t == a_packet) ? s->first->w.w_packet : -1;
- pdp_list_pop(s); //ownership is transferred to receiver, drop kills the packet
- return e_ok;
-}
-
-
-t_pdp_word_error pdp_stack_mov(t_pdp_stack *s)
-{
- int position;
- t_pdp_atom *a, *a_before;
- if (s->elements < 2) return e_underflow;
- if (s->first->t != a_int) return e_type;
-
- pdp_stack_pop_int(s, &position); // get insert point
- if (position < 1) return e_ok; // < 0 : invalid; do nothing, 0 : nop (= insert at start, but already at start)
- if ((s->elements-1) < position) return e_underflow;
-
- a = s->first; // get first atom
- s->first = a->next;
-
- if (s->elements-1 == position){ //insert at end
- s->last->next = a;
- a->next = 0;
- s->last = a;
- }
- else { //insert somewhere in the middle
- a_before = s->first;
- while (--position) a_before = a_before->next;
- a->next = a_before->next;
- a_before->next = a;
- }
- return e_ok;
-}
-
-/* rotate stack down (tos -> bottom) */
-t_pdp_word_error pdp_stack_rdown(t_pdp_stack *s)
-{
- t_pdp_word_type t = s->first->t;
- t_pdp_word w = s->first->w;
- pdp_list_pop(s);
- pdp_list_add_back(s, t, w);
- return e_ok;
-}
-
-
-/* convert to int */
-t_pdp_word_error pdp_stack_int(t_pdp_stack *s)
-{
- int i;
- pdp_stack_pop_int(s, &i);
- pdp_stack_push_int(s, i);
- return e_ok;
-}
-
-/* convert to float */
-t_pdp_word_error pdp_stack_float(t_pdp_stack *s)
-{
- float f;
- pdp_stack_pop_float(s, &f);
- pdp_stack_push_float(s, f);
- return e_ok;
-}
-
-
-#define OP1(name, type, op) \
-t_pdp_word_error pdp_stack_##name##_##type (t_pdp_stack *s) \
-{ \
- type x0; \
- pdp_stack_pop_##type (s, &(x0)); \
- pdp_stack_push_##type (s, op (x0)); \
- return e_ok; \
-}
-
-#define OP2(name, type, op) \
-t_pdp_word_error pdp_stack_##name##_##type (t_pdp_stack *s) \
-{ \
- type x0, x1; \
- pdp_stack_pop_##type (s, &(x0)); \
- pdp_stack_pop_##type (s, &(x1)); \
- pdp_stack_push_##type (s, x1 op x0); \
- return e_ok; \
-}
-
-/* some floating point and integer stuff */
-
-OP2(add, float, +);
-OP2(sub, float, -);
-OP2(mul, float, *);
-OP2(div, float, /);
-
-OP1(sin, float, sin);
-OP1(cos, float, cos);
-
-OP2(add, int, +);
-OP2(sub, int, -);
-OP2(mul, int, *);
-OP2(div, int, /);
-OP2(mod, int, %);
-
-OP2(and, int, &);
-OP2(or, int, |);
-OP2(xor, int, ^);
-
-
-/* some integer stuff */
-
-t_pdp_word_error pdp_stack_push_invalid_packet(t_pdp_stack *s)
-{
- pdp_stack_push_packet(s, -1);
- return e_ok;
-}
-
-/* dictionary manipulation */
-
-void pdp_forth_word_print_debug(t_pdp_symbol *s)
-{
- t_pdp_atom *a;
- if (!s->s_word_spec){
- post("%s is not a forth word", s->s_name);
- }
- else{
- post("");
- post("forth word %s", s->s_name);
- post("\tinput: %d", s->s_word_spec->input_size);
- post("\toutput: %d", s->s_word_spec->output_size);
- post("\ttype index: %d", s->s_word_spec->type_index);
-
- post("\nimplementations:");
- for(a=s->s_word_spec->implementations->first; a; a=a->next){
- t_pdp_forthword_imp *i = a->w.w_pointer;
- startpost("\t%s\t", i->type ? i->type->s_name : "anything");
- pdp_list_print(i->def);
-
- }
- post("");
- }
-}
-
-/* add a definition (list of high level words (symbols) or primitive routines) */
-void pdp_forthdict_add_word(t_pdp_symbol *name, t_pdp_list *def, int input_size, int output_size,
- int type_index, t_pdp_symbol *type)
-{
- t_pdp_forthword_spec *spec = 0;
- t_pdp_forthword_imp *imp = 0;
- t_pdp_forthword_imp *old_imp = 0;
- t_pdp_atom *a;
- /* check if the word complies to a previously defined word spec with the same name */
- if (spec = name->s_word_spec){
- if ((spec->input_size != input_size)
- ||(spec->output_size != output_size)
- ||(spec->type_index != type_index)){
- post("ERROR: pdp_forthdict_add_word: new implementation of [%s] does not comply to old spec",
- name->s_name);
- return;
- }
-
- }
- /* no previous word spec with this name, so create a new spec */
- else{
- spec = name->s_word_spec = (t_pdp_forthword_spec *)pdp_alloc(sizeof(t_pdp_forthword_spec));
- spec->name = name;
- spec->input_size = input_size;
- spec->output_size = output_size;
- spec->type_index = type_index;
- spec->implementations = pdp_list_new(0);
- }
-
- /* create the new implementation and add it */
- imp = (t_pdp_forthword_imp *)pdp_alloc(sizeof(t_pdp_forthword_imp));
- imp->name = name;
- imp->def = def;
- imp->type = type;
-
- /* can't delete old implemetations because of thread safety */
- pdp_list_add_pointer(spec->implementations, imp);
-
-}
-
-/* add a primitive */
-void pdp_forthdict_add_primitive(t_pdp_symbol *name, t_pdp_forthword w, int input_size, int output_size,
- int type_index, t_pdp_symbol *type)
-{
- t_pdp_list *def = pdp_list_new(1);
- def->first->t = a_pointer;
- def->first->w.w_pointer = w;
- pdp_forthdict_add_word(name, def, input_size, output_size, type_index, type);
-}
-
-/* parse a new definition from a null terminated string */
-t_pdp_list *pdp_forth_compile_def(char *chardef)
-{
- t_pdp_list *l;
- char *c;
-
- if (!(l = pdp_list_from_cstring(chardef, &c))){
- post ("ERROR: pdp_forth_compile_def: parse error parsing: %s", chardef);
- if (*c) post ("ERROR: remaining input: %s", c);
- }
- if (*c){
- post ("WARNING: pdp_forth_compile_def: parsing: %s", chardef);
- if (*c) post ("garbage at end of string: %s", c);
- }
-
- return l;
-
-}
-
-void pdp_forthdict_compile_word(t_pdp_symbol *name, char *chardef, int input_size, int output_size,
- int type_index, t_pdp_symbol *type)
-{
- /* add the definition list to the dictionary */
- t_pdp_list *def;
-
- if (def = pdp_forth_compile_def (chardef))
- pdp_forthdict_add_word(name, def, input_size, output_size, type_index, type);
-
-
-}
-
-
-
-/* execute a definition list
- a def list is a list of primitives, immediates or symbolic words */
-t_pdp_word_error pdp_forth_execute_def(t_pdp_stack *stack, t_pdp_list *def)
-{
- t_pdp_atom *a;
- t_pdp_word_error e;
- t_pdp_forthword w;
- float f;
- int i,p;
-
- D post("pdp_forth_execute_def %x %x", stack, def);
- D pdp_list_print(def);
-
- for (a = def->first; a; a=a->next){
- switch(a->t){
- case a_float: // an immidiate float
- f = a->w.w_float;
- D post("pushing %f onto the stack", f);
- pdp_stack_push_float(stack, f);
- break;
- case a_int: // an immidiate int
- i = a->w.w_int;
- D post("pushing %d onto the stack", i);
- pdp_stack_push_int(stack, i);
- break;
- case a_packet: // an immidiate int
- p = a->w.w_packet;
- D post("pushing packet %d onto the stack", p);
- pdp_stack_push_packet(stack, pdp_packet_copy_ro(p));
- break;
- case a_symbol: // a high level word or an immediate symbol
- D post("interpeting symbol %s", a->w.w_symbol->s_name);
- if (e = pdp_forth_execute_word(stack, a->w.w_symbol)) return e;
- break;
- case a_pointer: // a primitive
- w = a->w.w_pointer;
- D post("exec primitive %x", w);
- if (e = (w(stack))) return e;
- break;
- default:
- return e_internal;
-
- }
- }
- return e_ok;
-}
-
-/* execute a symbol (a high level word or an immediate)
- this routine does the type based word multiplexing and stack checking */
-t_pdp_word_error pdp_forth_execute_word(t_pdp_stack *stack, t_pdp_symbol *word)
-{
- t_pdp_symbol *type = 0;
- t_pdp_atom *a;
- t_pdp_forthword_spec *spec;
- t_pdp_forthword_imp *imp = 0;
- int i;
-
- D post("pdp_forth_execute_word %x %x", stack, word);
-
- /* first check if the word is defined. if not, the symbol will be loaded
- onto the stack as an immidiate symbol */
-
- if (!(spec = word->s_word_spec)){
- D post ("pushing symbol %s on the stack", word->s_name);
- pdp_stack_push_symbol(stack, word);
- return e_ok;
- }
-
- D post("exec high level word [%s]", word->s_name);
-
- /* it is a word. check the stack size */
- if (stack->elements < spec->input_size){
- D post ("error executing [%s]: stack underflow", word->s_name);
- return e_underflow;
- }
-
- /* if the word is type oblivious, symply execute the first (only)
- implementation in the list */
- if (spec->type_index < 0){
- D post("exec type oblivious word [%s]", word->s_name);
- imp = spec->implementations->first->w.w_pointer;
- return pdp_forth_execute_def(stack , imp->def);
- }
-
- /* if it is not type oblivious, find the type template
- to determine the correct implementation */
-
- for(i=spec->type_index,a=stack->first; i--; a=a->next);
- switch (a->t){
- /* get type description from first item on*/
- case a_packet:
- type = pdp_packet_get_description(a->w.w_packet); break;
- case a_symbol:
- type = a->w.w_symbol; break;
- case a_float:
- type = pdp_gensym("float"); break;
- case a_int:
- type = pdp_gensym("int"); break;
- case a_pointer:
- type = pdp_gensym("pointer"); break;
- default:
- /* no type description found on top of stack. */
- type = pdp_gensym("unknown");
- break;
- }
-
- /* scan the implementation list until a definition with matching type is found
- if the type spec for a word is NULL, it counts as a match (for generic words) */
- for (a = spec->implementations->first; a; a = a->next){
- imp = a->w.w_pointer;
- if ((!imp->type) || pdp_type_description_match(type, imp->type)){
- return pdp_forth_execute_def(stack , imp->def);
- }
- }
- D post("ERROR: pdp_forth_execute_word: type error executing [%s] (2). stack:",word->s_name);
- D pdp_list_print(stack);
-
- return e_type; // type error
-
-}
-
-
-static void _add_2op(char *name, t_pdp_forthword w, char *type){
- pdp_forthdict_add_primitive(pdp_gensym(name), w, 2, 1, 0, pdp_gensym(type));
-}
-
-static void _add_1op(char *name, t_pdp_forthword w, char *type){
- pdp_forthdict_add_primitive(pdp_gensym(name), w, 1, 1, 0, pdp_gensym(type));
-}
-
-
-void pdp_forth_setup(void)
-{
-
- /* add type oblivious (type_index = -1, type = NULL) stack manip primitives */
- pdp_forthdict_add_primitive(pdp_gensym("dup"), (t_pdp_forthword)pdp_stack_dup, 1, 2, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("swap"), (t_pdp_forthword)pdp_stack_swap, 2, 2, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("drop"), (t_pdp_forthword)pdp_stack_drop, 1, 0, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("over"), (t_pdp_forthword)pdp_stack_over, 2, 3, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("mov"), (t_pdp_forthword)pdp_stack_mov, 2, 1, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("down"), (t_pdp_forthword)pdp_stack_rdown, 1, 1, -1, 0);
-
- /* type converters (casts) */
- pdp_forthdict_add_primitive(pdp_gensym("int"), (t_pdp_forthword)pdp_stack_int, 1, 1, -1, 0);
- pdp_forthdict_add_primitive(pdp_gensym("float"), (t_pdp_forthword)pdp_stack_float, 1, 1, -1, 0);
-
- /* add floating point ops */
- _add_2op("add", (t_pdp_forthword)pdp_stack_add_float, "float");
- _add_2op("sub", (t_pdp_forthword)pdp_stack_sub_float, "float");
- _add_2op("mul", (t_pdp_forthword)pdp_stack_mul_float, "float");
- _add_2op("div", (t_pdp_forthword)pdp_stack_div_float, "float");
-
- _add_1op("sin", (t_pdp_forthword)pdp_stack_sin_float, "float");
- _add_1op("cos", (t_pdp_forthword)pdp_stack_cos_float, "float");
-
- /* add integer ops */
- _add_2op("add", (t_pdp_forthword)pdp_stack_add_int, "int");
- _add_2op("sub", (t_pdp_forthword)pdp_stack_sub_int, "int");
- _add_2op("mul", (t_pdp_forthword)pdp_stack_mul_int, "int");
- _add_2op("div", (t_pdp_forthword)pdp_stack_div_int, "int");
- _add_2op("mod", (t_pdp_forthword)pdp_stack_mod_int, "int");
-
- _add_2op("and", (t_pdp_forthword)pdp_stack_and_int, "int");
- _add_2op("or", (t_pdp_forthword)pdp_stack_or_int, "int");
- _add_2op("xor", (t_pdp_forthword)pdp_stack_xor_int, "int");
-
- /* some immidiates */
- pdp_forthdict_add_primitive(pdp_gensym("ip"), (t_pdp_forthword)pdp_stack_push_invalid_packet, 0, 1, -1, 0);
-
-}
diff --git a/system/kernel/pdp_list.c b/system/kernel/pdp_list.c
deleted file mode 100644
index ed2ad76..0000000
--- a/system/kernel/pdp_list.c
+++ /dev/null
@@ -1,663 +0,0 @@
-
-/*
- * Pure Data Packet header file. List class
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* who can live without a list, hmm? */
-
-/* rethink the list of list thing:
- should free and copy really copy the lists, or should
- references to lists be allowed too?
-
- maybe references to lists as generic pointers? */
-
-#include "pdp_list.h"
-#include "pdp_types.h"
-#include "pdp.h"
-#include <pthread.h>
-#include <stdlib.h>
-
-#define D if (0)
-
-#define PDP_LIST_BLOCKSIZE 4096
-
-#define PDP_ATOM_ALLOC _pdp_atom_reuse
-#define PDP_ATOM_DEALLOC _pdp_atom_save
-//#define PDP_ATOM_ALLOC _pdp_atom_alloc
-//#define PDP_ATOM_DEALLOC _pdp_atom_dealloc
-
-static t_pdp_atom *freelist;
-static t_pdp_list *blocklist;
-static pthread_mutex_t mut;
-
-/* memory allocation (for ease of wrapping) */
-static inline t_pdp_list* _pdp_list_alloc(void){return (t_pdp_list *)pdp_alloc(sizeof(t_pdp_list));}
-static inline void _pdp_list_dealloc(t_pdp_list *list){pdp_dealloc(list);}
-static inline t_pdp_atom* _pdp_atom_alloc(void){return (t_pdp_atom *)pdp_alloc(sizeof(t_pdp_atom));}
-static inline void _pdp_atom_dealloc(t_pdp_atom *a){pdp_dealloc(a);}
-
-
-
-/* some private helper methods */
-
-/* list pool setup */
-void pdp_list_setup(void)
-{
- freelist = 0;
- blocklist = _pdp_list_alloc();
- blocklist->elements = 0;
- blocklist->first = 0;
- pthread_mutex_init(&mut, NULL);
-
-#if 0
- {
- char *c = "(test 1 2 (23 4)) (een (zes (ze)ven ()))) (())";
- while (*c){
- t_pdp_list *l = pdp_list_from_char(c, &c);
- if (l) pdp_list_print(l);
- else{
- post("parse error: remaining input: %s", c); break;
- }
- }
- }
-#endif
-
-}
-
-/* allocate a block */
-static t_pdp_atom* _pdp_atom_block_alloc(int size)
-{
- int i = size;
- t_pdp_atom *atom_block, *atom;
- atom_block = (t_pdp_atom *)pdp_alloc(sizeof(t_pdp_atom) * size);
- atom = atom_block;
- while(i--){
- atom->next = atom + 1;
- atom->t = a_undef;
- atom->w.w_int = 0;
- atom++;
- }
- atom_block[size-1].next = 0;
- return atom_block;
-}
-
-static void _pdp_atomlist_fprint(FILE* f, t_pdp_atom *a);
-
-static void _pdp_atom_refill_freelist(void)
-{
- t_pdp_atom *atom;
-
- if (freelist != 0) post("ERROR:_pdp_atom_do_reuse: freelist != 0");
-
- /* get a new block */
- freelist = _pdp_atom_block_alloc(PDP_LIST_BLOCKSIZE);
- //post("new block");
- //_pdp_atomlist_fprint(stderr, freelist);
-
- /* take the first element from the block to serve as a blocklist element */
- atom = freelist;
- atom->t = a_pointer;
- atom->w.w_pointer = freelist;
- freelist = freelist->next;
- atom->next = blocklist->first;
- blocklist->first = atom;
- blocklist->elements++;
-
-}
-
-
-/* reuse an old element from the freelist, or allocate a new block */
-static inline t_pdp_atom* _pdp_atom_reuse(void)
-{
- t_pdp_atom *atom;
-
- pthread_mutex_lock(&mut);
-
- while (!(atom = freelist)){
- _pdp_atom_refill_freelist();
- }
- /* delete the element from the freelist */
- freelist = freelist->next;
- atom->next = 0;
-
- pthread_mutex_unlock(&mut);
-
- return atom;
-}
-
-static inline void _pdp_atom_save(t_pdp_atom *atom)
-{
- pthread_mutex_lock(&mut);
-
- atom->next = freelist;
- freelist = atom;
-
- pthread_mutex_unlock(&mut);
-}
-
-
-
-
-
-
-/* create a list */
-t_pdp_list* pdp_list_new(int elements)
-{
- t_pdp_atom *a = 0;
- t_pdp_list *l = _pdp_list_alloc();
- l->elements = 0;
- if (elements){
- a = PDP_ATOM_ALLOC();
- l->elements++;
- a->t = a_undef;
- a->w.w_int = 0;
- a->next = 0;
- elements--;
- }
- l->first = a;
- l->last = a;
-
- while (elements--){
- a = PDP_ATOM_ALLOC();
- l->elements++;
- a->t = a_undef;
- a->w.w_int = 0;
- a->next = l->first;
- l->first = a;
- }
- return l;
-}
-
-/* clear a list */
-void pdp_list_clear(t_pdp_list *l)
-{
- t_pdp_atom *a = l->first;
- t_pdp_atom *next_a;
-
- while(a){
- next_a = a->next;
- PDP_ATOM_DEALLOC(a);
- a = next_a;
- }
- l->first = 0;
- l->last = 0;
- l->elements = 0;
-}
-
-/* destroy a list */
-void pdp_list_free(t_pdp_list *l)
-{
- if (l){
- pdp_list_clear(l);
- _pdp_list_dealloc(l);
- }
-}
-
-
-/* destroy a (sub)tree */
-void pdp_tree_free(t_pdp_list *l)
-{
- if (l) {
- pdp_tree_clear(l);
- _pdp_list_dealloc(l);
- }
-}
-
-/* clear a tree */
-void pdp_tree_clear(t_pdp_list *l)
-{
- t_pdp_atom *a = l->first;
- t_pdp_atom *next_a;
-
- while(a){
- if (a->t == a_list) pdp_tree_free(a->w.w_list);
- next_a = a->next;
- PDP_ATOM_DEALLOC(a);
- a = next_a;
- }
- l->first = 0;
- l->last = 0;
- l->elements = 0;
-}
-
-
-static inline int _is_whitespace(char c){return (c == ' ' || c == '\n' || c == '\t');}
-static inline void _skip_whitespace(char **c){while (_is_whitespace(**c)) (*c)++;}
-static inline int _is_left_separator(char c) {return (c == '(');}
-static inline int _is_right_separator(char c) {return (c == ')');}
-static inline int _is_separator(char c) {return (_is_left_separator(c) || _is_right_separator(c) || _is_whitespace(c));}
-
-
-static inline void _parse_atom(t_pdp_word_type *t, t_pdp_word *w, char *c, int n)
-{
- char tmp[n+1];
- //post("_parse_atom(%d, %x, %s, %d)", *t, w, c, n);
- strncpy(tmp, c, n);
- tmp[n] = 0;
-
-
- /* check if it's a number */
- if (tmp[0] >= '0' && tmp[0] <= '9'){
- int is_float = 0;
- char *t2;
- for(t2 = tmp; *t2; t2++){
- if (*t2 == '.') {
- is_float = 1;
- break;
- }
- }
- /* it's a float */
- if (is_float){
- float f = strtod(tmp, 0);
- D post("adding float %f", f);
- *t = a_float;
- *w = (t_pdp_word)f;
- }
-
- /* it's an int */
- else {
- int i = strtol(tmp, 0, 0);
- D post("adding int %d", i);
- *t = a_int;
- *w = (t_pdp_word)i;
- }
-
- }
- /* it's a symbol */
- else {
- D post("adding symbol %s", tmp);
- *t = a_symbol;
- *w = (t_pdp_word)pdp_gensym(tmp);
- }
-
- D post("done parsing atom");
-
-}
-
-
-/* create a list from a character string */
-t_pdp_list *pdp_list_from_cstring(char *chardef, char **nextchar)
-{
- t_pdp_list *l = pdp_list_new(0);
- char *c = chardef;
- char *lastname = c;
- int n = 0;
-
- D post ("creating list from char: %s", chardef);
-
- /* find opening parenthesis and skip it*/
- _skip_whitespace(&c);
- if (!_is_left_separator(*c)) goto error; else c++;
-
- /* start counting at the first non-whitespace
- character after opening parenthesis */
- _skip_whitespace(&c);
- lastname = c;
- n = 0;
-
- while(*c){
- if (!_is_separator(*c)){
- /* item not terminated: keep counting */
- c++;
- n++;
- }
- else {
- /* separator encountered whitespace or parenthesis */
-
- if (n){
- /* if there was something between this and the previous
- separator, we've found and atom and parse it */
- pdp_list_add_back(l, a_undef, (t_pdp_word)0);
- _parse_atom(&l->last->t, &l->last->w, lastname, n);
-
- /* skip the whitespace after the parsed word, if any */
- _skip_whitespace(&c);
- }
-
- /* if we're at a right separator, we're done */
- if (_is_right_separator(*c)) {c++; goto done;}
-
- /* if it's a left separater, we have a sublist */
- if (_is_left_separator(*c)){
- t_pdp_list *sublist = pdp_list_from_cstring(c, &c);
- if (!sublist) goto error; //sublist had parse error
- pdp_list_add_back(l, a_list, (t_pdp_word)sublist);
- }
-
- /* prepare for next atom */
- lastname = c;
- n = 0;
- }
-
- }
-
- error:
- /* end of string encountered: parse error */
- D post("parse error: %s", c);
- if (nextchar) *nextchar = c;
- pdp_tree_free(l); //this will free all sublists too
- return 0;
-
-
- done:
- _skip_whitespace(&c);
- if (nextchar) *nextchar = c;
- return l;
-
-
-
-}
-
-
-/* traversal */
-void pdp_list_apply(t_pdp_list *l, t_pdp_atom_method m)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next) m(a);
-}
-
-void pdp_tree_apply(t_pdp_list *l, t_pdp_atom_method m)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next){
- if (a->t == a_list) pdp_tree_apply(a->w.w_list, m);
- else m(a);
- }
-}
-
-void pdp_list_apply_word_method(t_pdp_list *l,
- t_pdp_word_type type, t_pdp_word_method wm)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next){
- if (a->t == type) wm(a->w);
- }
-}
-void pdp_list_apply_pword_method(t_pdp_list *l,
- t_pdp_word_type type, t_pdp_pword_method pwm)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next){
- if (a->t == type) pwm(&a->w);
- }
-}
-
-void pdp_tree_apply_word_method(t_pdp_list *l,
- t_pdp_word_type type, t_pdp_word_method wm)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next){
- if (a->t == a_list) pdp_tree_apply_word_method(a->w.w_list, type, wm);
- else if (a->t == type) wm(a->w);
- }
-}
-void pdp_tree_apply_pword_method(t_pdp_list *l,
- t_pdp_word_type type, t_pdp_pword_method pwm)
-{
- t_pdp_atom *a;
- if (!l) return;
- for (a=l->first; a; a=a->next){
- if (a->t == a_list) pdp_tree_apply_pword_method(a->w.w_list, type ,pwm);
- else if (a->t == type) pwm(&a->w);
- }
-}
-
-static void _atom_packet_mark_unused(t_pdp_atom *a)
-{
- if (a->t == a_packet){
- pdp_packet_mark_unused(a->w.w_packet);
- a->t = a_undef;
- a->w.w_int = 0;
- }
-}
-
-void pdp_tree_strip_packets (t_pdp_list *l)
-{
- pdp_tree_apply(l, _atom_packet_mark_unused);
-}
-
-
-/* debug */
-static void _pdp_atomlist_fprint(FILE* f, t_pdp_atom *a)
-{
- fprintf(f, "(");
- while (a){
- switch(a->t){
- case a_symbol: fprintf(f, "%s",a->w.w_symbol->s_name); break;
- case a_float: fprintf(f, "%f",a->w.w_float); break;
- case a_int: fprintf(f, "%d",a->w.w_int); break;
- case a_packet: fprintf(f, "#<pdp %d %s>",a->w.w_packet,
- pdp_packet_get_description(a->w.w_packet)->s_name); break;
- case a_pointer: fprintf(f, "#<0x%08x>",(unsigned int)a->w.w_pointer); break;
- case a_list: _pdp_atomlist_fprint(f, a->w.w_list->first); break;
- case a_undef: fprintf(f, "undef"); break;
-
- default: fprintf(f, "unknown"); break;
- }
- a = a->next;
- if (a) fprintf(f, " ");
- }
- fprintf(f, ")");
-}
-
-void _pdp_list_fprint(FILE* f, t_pdp_list *l)
-{
- _pdp_atomlist_fprint(f, l->first);
- fprintf(f, "\n");
-}
-
-void pdp_list_print(t_pdp_list *l)
-{
- _pdp_list_fprint(stderr, l);
-}
-
-
-/* public list operations */
-
-
-/* add a word to the start of the list */
-void pdp_list_add(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w)
-{
- t_pdp_atom *new_a = PDP_ATOM_ALLOC();
- l->elements++;
- new_a->next = l->first;
- new_a->w = w;
- new_a->t = t;
- l->first = new_a;
- if (!l->last) l->last = new_a;
-}
-
-
-/* add a word to the end of the list */
-void pdp_list_add_back(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w)
-{
- t_pdp_atom *new_a = PDP_ATOM_ALLOC();
- l->elements++;
- new_a->next = 0;
- new_a->w = w;
- new_a->t = t;
- if (l->last){
- l->last->next = new_a;
- }
- else{
- l->first = new_a;
- }
- l->last = new_a;
-}
-
-/* get list size */
-int pdp_list_size(t_pdp_list *l)
-{
- return l->elements;
-}
-
-
-
-
-/* pop: return first item and remove */
-t_pdp_word pdp_list_pop(t_pdp_list *l)
-{
- t_pdp_atom *a = l->first;
- t_pdp_word w;
-
- w = a->w;
- l->first = a->next;
- PDP_ATOM_DEALLOC(a);
- l->elements--;
- if (!l->first) l->last = 0;
-
- return w;
-}
-
-
-/* return element at index */
-t_pdp_word pdp_list_index(t_pdp_list *l, int index)
-{
- t_pdp_atom *a;
- for (a = l->first; index--; a = a->next);
- return a->w;
-}
-
-
-
-
-
-/* remove an element from a list */
-void pdp_list_remove(t_pdp_list *l, t_pdp_word_type t, t_pdp_word w)
-{
- t_pdp_atom head;
- t_pdp_atom *a;
- t_pdp_atom *kill_a;
- head.next = l->first;
-
- for(a = &head; a->next; a = a->next){
- if (a->next->w.w_int == w.w_int && a->next->t == t){
- kill_a = a->next; // element to be killed
- a->next = a->next->next; // remove link
- PDP_ATOM_DEALLOC(kill_a);
- l->elements--;
- l->first = head.next; // restore the start pointer
- if (l->last == kill_a) { // restore the end pointer
- l->last = (a != &head) ? a : 0;
- }
-
- break;
- }
- }
-
-}
-
-
-
-
-
-/* copy a list */
-t_pdp_list* pdp_tree_copy_reverse(t_pdp_list *list)
-{
- t_pdp_list *newlist = pdp_list_new(0);
- t_pdp_atom *a;
- for (a = list->first; a; a = a->next)
- if (a->t == a_list){
- pdp_list_add(newlist, a->t,
- (t_pdp_word)pdp_tree_copy_reverse(a->w.w_list));
- }
- else{
- pdp_list_add(newlist, a->t, a->w);
- }
- return newlist;
-}
-t_pdp_list* pdp_list_copy_reverse(t_pdp_list *list)
-{
- t_pdp_list *newlist = pdp_list_new(0);
- t_pdp_atom *a;
- for (a = list->first; a; a = a->next)
- pdp_list_add(newlist, a->t, a->w);
- return newlist;
-}
-
-t_pdp_list* pdp_tree_copy(t_pdp_list *list)
-{
- t_pdp_list *newlist = pdp_list_new(list->elements);
- t_pdp_atom *a_src = list->first;
- t_pdp_atom *a_dst = newlist->first;
-
- while(a_src){
- a_dst->t = a_src->t;
- if (a_dst->t == a_list){ //recursively copy sublists (tree copy)
- a_dst->w.w_list = pdp_tree_copy(a_src->w.w_list);
- }
- else{
- a_dst->w = a_src->w;
- }
- a_src = a_src->next;
- a_dst = a_dst->next;
- }
-
- return newlist;
-}
-t_pdp_list* pdp_list_copy(t_pdp_list *list)
-{
- t_pdp_list *newlist = pdp_list_new(list->elements);
- t_pdp_atom *a_src = list->first;
- t_pdp_atom *a_dst = newlist->first;
-
- while(a_src){
- a_dst->t = a_src->t;
- a_dst->w = a_src->w;
- a_src = a_src->next;
- a_dst = a_dst->next;
- }
- return newlist;
-}
-
-void pdp_list_cat (t_pdp_list *l, t_pdp_list *tail)
-{
- t_pdp_list *tmp = pdp_list_copy(tail);
- l->elements += tmp->elements;
- l->last->next = tmp->first;
- l->last = tmp->last;
- _pdp_list_dealloc(tmp); //delete the list stub
-
-}
-
-
-/* check if a list contains an element */
-int pdp_list_contains(t_pdp_list *list, t_pdp_word_type t, t_pdp_word w)
-{
- t_pdp_atom *a;
- for(a = list->first; a; a=a->next){
- if (a->w.w_int == w.w_int && a->t == t) return 1;
- }
- return 0;
-}
-
-/* add a thing to the start of the list if it's not in there already */
-void pdp_list_add_to_set(t_pdp_list *list, t_pdp_word_type t, t_pdp_word w)
-{
- if (!pdp_list_contains(list, t, w))
- pdp_list_add(list, t, w);
-}
-
-
-
diff --git a/system/kernel/pdp_mem.c b/system/kernel/pdp_mem.c
deleted file mode 100644
index 33822ef..0000000
--- a/system/kernel/pdp_mem.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Pure Data Packet system file: memory allocation
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include "pdp_mem.h"
-#include "pdp_debug.h"
-
-
-/* malloc wrapper that calls garbage collector */
-void *pdp_alloc(int size)
-{
- void *ptr = malloc(size);
-
- PDP_ASSERT(ptr);
-
- return ptr;
-
- //TODO: REPAIR THIS
- //post ("malloc failed in a pdp module: running garbage collector.");
- //pdp_pool_collect_garbage();
- //return malloc(size);
-}
-
-
-void pdp_dealloc(void *stuff)
-{
- free (stuff);
-}
-
-
-/* fast atom allocation object
- well, this is not too fast yet, but will be later
- when it suports linux futexes or atomic operations */
-
-//#include <pthread.h>
-
-/* private linked list struct */
-typedef struct _fastalloc
-{
- struct _fastalloc * next;
-} t_fastalloc;
-
-
-
-
-static void _pdp_fastalloc_lock(t_pdp_fastalloc *x){pthread_mutex_lock(&x->mut);}
-static void _pdp_fastalloc_unlock(t_pdp_fastalloc *x){pthread_mutex_unlock(&x->mut);}
-
-static void _pdp_fastalloc_refill_freelist(t_pdp_fastalloc *x)
-{
- t_fastalloc *atom;
- unsigned int i;
-
- PDP_ASSERT(x->freelist == 0);
-
- /* get a new block
- there is no means of freeing the data afterwards,
- this is a fast implementation with the tradeoff of data
- fragmentation "memory leaks".. */
-
- x->freelist = pdp_alloc(x->block_elements * x->atom_size);
-
- /* link all atoms together */
- atom = x->freelist;
- for (i=0; i<x->block_elements-1; i++){
- atom->next = (t_fastalloc *)(((char *)atom) + x->atom_size);
- atom = atom->next;
- }
- atom->next = 0;
-
-}
-
-void *pdp_fastalloc_new_atom(t_pdp_fastalloc *x)
-{
- t_fastalloc *atom;
-
- _pdp_fastalloc_lock(x);
-
- /* get an atom from the freelist
- or refill it and try again */
- while (!(atom = x->freelist)){
- _pdp_fastalloc_refill_freelist(x);
- }
-
- /* delete the element from the freelist */
- x->freelist = x->freelist->next;
- atom->next = 0;
-
- _pdp_fastalloc_unlock(x);
-
- return (void *)atom;
-
-}
-void pdp_fastalloc_save_atom(t_pdp_fastalloc *x, void *atom)
-{
- _pdp_fastalloc_lock(x);
- ((t_fastalloc *)atom)->next = x->freelist;
- x->freelist = (t_fastalloc *)atom;
- _pdp_fastalloc_unlock(x);
-}
-
-t_pdp_fastalloc *pdp_fastalloc_new(unsigned int size)
-{
- t_pdp_fastalloc *x = pdp_alloc(sizeof(*x));
- if (size < sizeof(t_fastalloc)) size = sizeof(t_fastalloc);
- x->freelist = 0;
- x->atom_size = size;
- x->block_elements = PDP_FASTALLOC_BLOCK_ELEMENTS;
- pthread_mutex_init(&x->mut, NULL);
- return x;
-}
-
diff --git a/system/kernel/pdp_packet.c b/system/kernel/pdp_packet.c
deleted file mode 100644
index a811381..0000000
--- a/system/kernel/pdp_packet.c
+++ /dev/null
@@ -1,957 +0,0 @@
-/*
- * Pure Data Packet system implementation: Packet Manager
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-#include "pdp.h"
-#include <stdio.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <string.h>
-
-
-/* TODO:
- implement an indexing system to the packet pool (array) to speed up searches.
- -> a list of lists of recycled packes, arranged by packet type.
- -> a list of unused slots
-*/
-
-
-
-#define D if (0)
-
-/* all symbols are C style */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-/* pdp specific constants */
-#define PDP_ALIGN 8
-
-/* this needs to be able to grow dynamically, think about it later */
-/* for ordinary work, this is enough and can help finding memory leaks */
-
-#define PDP_INITIAL_POOL_SIZE 1
-#define PDP_PACKET_MAX_MEM_USAGE -1
-
-/* the pool */
-static unsigned int pdp_packet_mem_usage;
-static unsigned int pdp_packet_max_mem_usage;
-static int pdp_pool_size;
-static t_pdp** pdp_pool;
-
-/* this is for detecting memory leaks */
-static int pdp_packet_count;
-
-/* some global vars */
-static t_symbol* pdp_sym_register_rw;
-static t_symbol* pdp_sym_register_ro;
-static t_symbol* pdp_sym_process;
-
-/* mutex */
-static pthread_mutex_t pdp_pool_mutex;
-
-/* the list of classes */
-static t_pdp_list *class_list;
-
-/* debug */
-void
-pdp_packet_print_debug(int packet)
-{
- t_pdp *h = pdp_packet_header(packet);
- post("debug info for packet %d", packet);
- if (!h){
- post("invalid packet");
- }
- else{
- post ("\ttype: %d", h->type);
- post ("\tdesc: %s", h->desc ? h->desc->s_name : "unknown");
- post ("\tsize: %d", h->size);
- post ("\tflags: %x", h->flags);
- post ("\tusers: %d", h->users);
- post ("\trefloc: %x", h->refloc);
- post ("\tclass: %x", h->theclass);
- }
-}
-
-
-
-/* setup methods */
-
-void
-pdp_packet_setup(void)
-{
-
- pdp_pool_size = PDP_INITIAL_POOL_SIZE;
- pdp_packet_count = 0;
- pdp_packet_mem_usage = 0;
- pdp_packet_max_mem_usage = PDP_PACKET_MAX_MEM_USAGE;
- pdp_pool = (t_pdp **)malloc(PDP_INITIAL_POOL_SIZE * sizeof(t_pdp *));
- bzero(pdp_pool, pdp_pool_size * sizeof(t_pdp *));
- pdp_sym_register_rw = gensym("register_rw");
- pdp_sym_register_ro = gensym("register_ro");
- pdp_sym_process = gensym("process");
- pdp_packet_count = 0;
- class_list = pdp_list_new(0);
-
- pthread_mutex_init(&pdp_pool_mutex, NULL);
-}
-
-/* class methods */
-t_pdp_class *pdp_class_new(t_pdp_symbol *type, t_pdp_factory_method create){
- t_pdp_class *c = (t_pdp_class *)pdp_alloc(sizeof(t_pdp_class));
- memset(c, 0, sizeof(t_pdp_class));
- c->create = create;
- c->type = type; // set type
- //c->attributes = pdp_list_new(0); // create an empty attribute list
- pdp_list_add(class_list, a_pointer, (t_pdp_word)((void *)c));
- //post("added class %s %x", c->type->s_name, c->create);
-
- return c;
-}
-
-#if 0
-void pdp_class_addmethod(t_pdp_class *c, t_pdp_symbol *name, t_pdp_attribute_method method,
- t_pdp_list *in_spec, t_pdp_list *out_spec)
-{
- t_pdp_attribute *attr = (t_pdp_attribute *)pdp_alloc(sizeof(t_pdp_attribute));
- attr->name = name;
- attr->method = method;
- attr->in_spec = in_spec;
- attr->out_spec = out_spec;
- pdp_list_add_pointer(c->attributes, attr);
-
-}
-#endif
-
-/* the packet factory */
-int pdp_factory_newpacket(t_pdp_symbol *type)
-{
- t_pdp_class *c;
- t_pdp_atom *a = class_list->first;
- while(a){
- c = (t_pdp_class *)(a->w.w_pointer);
- if (c->type && pdp_type_description_match(type, c->type)){
- //post("method %x, type %s", c->create, type->s_name);
- return (c->create) ? (*c->create)(type) : -1;
- }
- a = a->next;
- }
- return -1;
-}
-
-#if 0
-/* generic methods. actually a forth word operation on a stack.
- first item on stack must be a packet and it's type will
- determine the place to look for the operator */
-int pdp_packet_op(t_pdp_symbol *operation, struct _pdp_list *stack)
-{
- int packet = stack->first->w.w_packet;
- t_pdp *h = pdp_packet_header(packet);
- t_pdp_atom *i;
- t_pdp_attribute *attr;
-
- if (!(h && h->theclass)) goto exit;
-
- PDP_POINTER_IN(h->theclass->attributes, i, attr){
- //post("attribute:%s", attr->name->s_name);
- if (attr->name == operation){
-
- /* FOUND -> exec (check arguments first ???) */
- return attr->method (stack);
- }
-
- }
- exit:
- // method not found
- post ("WARNING: pdp_packet_op: packet %d from class %s has no operation %s",
- packet, (h && h->theclass) ? h->theclass->type->s_name : "UNKNOWN", operation->s_name);
- return 0;
-}
-
-#endif
-
-static void
-_pdp_pool_expand(void){
- int i;
-
- /* double the size */
- int new_pool_size = pdp_pool_size << 1;
- t_pdp **new_pool = (t_pdp **)malloc(new_pool_size * sizeof(t_pdp *));
- bzero(new_pool, new_pool_size * sizeof(t_pdp *));
- memcpy(new_pool, pdp_pool, pdp_pool_size * sizeof(t_pdp *));
- free(pdp_pool);
- pdp_pool = new_pool;
- pdp_pool_size = new_pool_size;
-
- D post("DEBUG: _pdp_pool_expand: resized pool to contain %d packets", pdp_pool_size);
-}
-
-
-
-
-/* private _pdp_packet methods */
-
-/* packets can only be created and destroyed using these 2 methods */
-/* it updates the mem usage and total packet count */
-
-static void
-_pdp_packet_dealloc(t_pdp *p)
-{
- unsigned int size = p->size;
- if (p->theclass && p->theclass->cleanup)
- (*p->theclass->cleanup)(p);
-
- free (p);
- pdp_packet_mem_usage -= size;
- pdp_packet_count--;
- D post("DEBUG: _pdp_packet_new_dealloc: freed packet. pool contains %d packets", pdp_packet_count);
-}
-
-static t_pdp*
-_pdp_packet_alloc(unsigned int datatype, unsigned int datasize)
-{
- unsigned int totalsize = datasize + PDP_HEADER_SIZE;
- unsigned int align;
- t_pdp *p = 0;
-
- /* check if there is a memory usage limit */
- if (pdp_packet_max_mem_usage){
- /* if it would exceed the limit, fail */
- if (pdp_packet_mem_usage + totalsize > pdp_packet_max_mem_usage){
- D post("DEBUG: _pdp_packet_new_alloc: memory usage limit exceeded");
- return 0;
- }
- }
- p = (t_pdp *)malloc(totalsize);
- if (p){
- align = ((unsigned int)p) & (PDP_ALIGN - 1);
- if (align) post("WARNING: _pdp_packet_alloc: data misaligned by %x", align);
- memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0
- p->type = datatype;
- p->size = totalsize;
- p->users = 1;
- pdp_packet_mem_usage += totalsize;
- pdp_packet_count++;
- D post("DEBUG: _pdp_packet_new_alloc: allocated new packet. pool contains %d packets, using %d bytes",
- pdp_packet_count, pdp_packet_mem_usage);
- }
-
- return p;
-}
-
-
-void
-pdp_packet_destroy(void)
-{
- int i = 0;
- /* dealloc all the data in object stack */
- post("DEBUG: pdp_packet_destroy: clearing object pool.");
- while ((i < pdp_pool_size) && (pdp_pool[i])) _pdp_packet_dealloc(pdp_pool[i++]);
-}
-
-
-
-/* try to find a packet based on main type and datasize */
-static int
-_pdp_packet_reuse_type_size(unsigned int datatype, unsigned int datasize)
-{
- unsigned int totalsize = datasize + PDP_HEADER_SIZE;
- int i = 0;
- int return_packet = -1;
- t_pdp* p;
-
- for (i=0; i < pdp_pool_size; i++){
- p = pdp_pool[i];
- /* check if we can reuse this one if it is already allocated */
- if (p) {
- /* search for unused packets of equal size & type */
- if ((p->users == 0) && (p->size == totalsize) && (p->type == datatype)){
- D post("DEBUG: _pdp_packet_reuse_type_size: can reuse %d", i);
-
- /* if possible, a packet will be reused and reinitialized
- i haven't found a use for this, so it's only used for discriminating
- between pure and not-so-pure packets */
- if (p->theclass && p->theclass->reinit){
- (*p->theclass->reinit)(p);
- }
- /* if no re-init method is found, the header will be reset to all 0
- this ensures the header is in a predictable state */
- else {
- memset(p, 0, PDP_HEADER_SIZE);
- p->type = datatype;
- p->size = totalsize;
- }
-
- p->users = 1;
- return_packet = i;
- goto exit;
- }
- else{
- D post("DEBUG _pdp_packet_reuse_type_size: can't reuse %d, (%d users)", i, p->users);
- }
- }
- }
-
- D post("DEBUG: _pdp_packet_reuse_type_size: no reusable packet found");
-
- exit:
- return return_packet;
-}
-
-
-/* create a new packet in an empty slot.
- if this fails, the garbage collector needs to be called */
-static int
-_pdp_packet_create_in_empty_slot(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- unsigned int totalsize = datasize + PDP_HEADER_SIZE;
- int i = 0;
- int return_packet = -1;
- int out_of_mem = 0;
- t_pdp* p;
-
-
- /* no reusable packets found, try to find an empty slot */
- for (i=0; i < pdp_pool_size; i++){
- p = pdp_pool[i];
- if (!p) {
- p = _pdp_packet_alloc(datatype, datasize);
-
- if (!p) {
- D post("DEBUG: _pdp_packet_create_in_empty_slot: out of memory (malloc returned NULL)");
- return_packet = -1;
- goto exit;
- }
-
- pdp_pool[i] = p;
- return_packet = i;
- goto exit;
- }
- }
-
- /* if we got here the pool is full: resize the pool and try again */
- _pdp_pool_expand();
- return_packet = _pdp_packet_create_in_empty_slot(datatype, datasize);
-
- exit:
- return return_packet;
-
-}
-
-/* find an unused packet, free it and create a new packet.
- if this fails, something is seriously wrong */
-static int
-_pdp_packet_create_in_unused_slot(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- unsigned int totalsize = datasize + PDP_HEADER_SIZE;
- int i = 0;
- int return_packet = -1;
- int out_of_mem = 0;
- t_pdp* p;
-
- D post("DEBUG: _pdp_packet_create_in_unused_slot: collecting garbage");
-
- /* search backwards */
- for (i=pdp_pool_size-1; i >= 0; i--){
- p = pdp_pool[i];
- if (p){
- if (p->users == 0){
- _pdp_packet_dealloc(p);
- p = _pdp_packet_alloc(datatype, datasize);
- pdp_pool[i] = p;
-
- /* alloc succeeded, return */
- if (p) {
- post("DEBUG _pdp_packet_create_in_unused_slot: garbage collect succesful");
- return_packet = i;
- goto exit;
- }
-
- /* alloc failed, continue collecting garbage */
- D post("DEBUG _pdp_packet_create_in_unused_slot: freed one packet, still out of memory (malloc returned NULL)");
- out_of_mem = 1;
-
- }
- }
- }
-
- /* if we got here, we ran out of memory */
- D post("DEBUG: _pdp_packet_create_in_unused_slot: out of memory after collecting garbage");
- return_packet = -1;
-
-exit:
- return return_packet;
-}
-
-/* warning: for "not so pure" packets, this method will only return an initialized
- packet if it can reuse a privious one. that is, if it finds a reinit method
- in the packet. use the pdp_packet_new_<type> constructor if possible */
-
-static int
-_pdp_packet_brandnew(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- int return_packet = -1;
-
- /* try to create a new packet in an empty slot */
- return_packet = _pdp_packet_create_in_empty_slot(datatype, datasize);
- if (return_packet != -1) goto exit;
-
- /* if we still don't have a packet, we need to call the garbage collector until we can allocate */
- return_packet = _pdp_packet_create_in_unused_slot(datatype, datasize);
-
- exit:
- return return_packet;
-}
-
-
-static int
-_pdp_packet_new(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- int return_packet = -1;
-
- /* try to reuse a packet based on main type and datasize */
- return_packet = _pdp_packet_reuse_type_size(datatype, datasize);
- if (return_packet != -1) goto exit;
-
- /* create a brandnew packet */
- return_packet = _pdp_packet_brandnew(datatype, datasize);
- if (return_packet != -1) goto exit;
-
- post("WARNING: maximum packet memory usage limit (%d bytes) reached after garbage collect.", pdp_packet_max_mem_usage);
- post("WARNING: increase memory limit or decrease packet usage (i.e. pdp_loop, pdp_delay).");
- post("WARNING: pool contains %d packets, using %d bytes.", pdp_packet_count, pdp_packet_mem_usage);
-
- exit:
- return return_packet;
-
-}
-
-
-
-/* public pool operations: have to be thread safe so each entry point
- locks the mutex */
-
-/* reuse an old packet based on high level description */
-int
-pdp_packet_reuse(t_pdp_symbol *description)
-{
- int i;
- int return_packet = -1;
- t_pdp *p;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- for (i=0; i < pdp_pool_size; i++){
- p = pdp_pool[i];
- /* check if we can reuse this one if it is already allocated */
- if ((p) && (p->users == 0) && (p->desc == description)){
- /* mark it as used */
- p->users = 1;
- return_packet = i;
- goto gotit;
- }
- }
-
- gotit:
- /* LOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
- return return_packet;
-
-
-}
-
-/* create a new packet, or reuse an old one based on main type and size */
-int
-pdp_packet_new(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- int packet;
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- packet = _pdp_packet_new(datatype, datasize);
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
- return packet;
-}
-
-
-/* create a brand new packet, don't reuse an old one */
-int
-pdp_packet_brandnew(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- int packet;
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- packet = _pdp_packet_brandnew(datatype, datasize);
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
- return packet;
-}
-
-
-/* this returns a copy of a packet for read only access. */
-int
-pdp_packet_copy_ro(int handle)
-{
- int out_handle = -1;
- t_pdp* p;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- if ((handle >= 0)
- && (handle < pdp_pool_size)
- && (p = pdp_pool[handle])){
-
- /* it is an error to copy a packet without an owner */
- if (!p->users){
- post("pdp_packet_copy_ro: ERROR: request to copy packet %d which has 0 users", handle);
- out_handle = -1;
- }
-
- /* if it's a passing packet, reset the reference location
- and turn it into a normal packet */
- else if (p->refloc){
- *p->refloc = -1;
- p->refloc = 0;
- out_handle = handle;
- }
- /* if it's a normal packet, increase the number of users */
- else {
- p->users++;
- out_handle = handle;
- }
- }
- else out_handle = -1;
-
- //post("pdp_copy_ro: outhandle:%d", out_handle);
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
- return out_handle;
-}
-
-/* copy a packet. if the packet is marked passing, it will be aquired.
- otherwize a new packet will be created with a copy of the contents. */
-
-int
-pdp_packet_copy_rw(int handle)
-{
- int out_handle = -1;
- t_pdp* p;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- if ((handle >= 0)
- && (handle < pdp_pool_size)
- && (p = pdp_pool[handle])){
- /* if there are other users, copy the object otherwize return the same handle */
-
- /* it is an error to copy a packet without an owner */
- if (!p->users){
- post("pdp_packet_copy_rw: ERROR: request to copy packet %d which has 0 users", handle);
- out_handle = -1;
- }
-
- /* if it is a passing packet, remove the owner's reference to it */
- else if (p->refloc){
- *p->refloc = -1;
- p->refloc = 0;
- out_handle = handle;
- }
-
- /* check if packet supports copy (for fanout) */
- else if(p->flags & PDP_FLAG_DONOTCOPY) out_handle = -1;
-
-
- /* copy the packet, since it already has 1 or more users */
- else{
- int new_handle = _pdp_packet_new(p->type, p->size - PDP_HEADER_SIZE);
- t_pdp* new_p = pdp_packet_header(new_handle);
-
- /* check if valid */
- if (!new_p) out_handle = -1;
-
- else {
- /* if a copy constructor is found, it will be called */
- if (p->theclass && p->theclass->copy){
- (*p->theclass->copy)(new_p, p);
- }
- /* if not, the entire packet will be copied, assuming a pure data packet */
- else {
- memcpy(new_p, p, p->size);
- }
- new_p->users = 1;
- out_handle = new_handle;
- }
- }
-
- //post("pdp_copy_rw: inhandle:%d outhandle:%d", handle, out_handle);
-
- }
- else out_handle = -1;
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
- return out_handle;
-}
-
-/* create a new packet, copying the header data of another
- packet, without copying the data */
-int
-pdp_packet_clone_rw(int handle)
-{
- int out_handle;
- t_pdp* p;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- if ((handle >= 0)
- && (handle < pdp_pool_size)
- && (p = pdp_pool[handle])){
-
- /* clone the packet header, don't copy the data */
- int new_handle = _pdp_packet_new(p->type, p->size - PDP_HEADER_SIZE);
- t_pdp* new_p = pdp_packet_header(new_handle);
-
- /* if a clone initializer is found, it will be called */
- if (p->theclass && p->theclass->clone){
- (*p->theclass->clone)(new_p, p);
- }
- /* if not, just the header will be copied, assuming a pure data packet */
- else {
- memcpy(new_p, p, PDP_HEADER_SIZE);
- }
- new_p->users = 1; /* the new packet has 1 user */
- new_p->refloc = 0; /* it is not a passing packet, even if the template was */
- out_handle = new_handle;
- }
-
- else out_handle = -1;
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
- return out_handle;
-}
-
-void
-_pdp_packet_mark_unused_nolock(int handle)
-{
- t_pdp* p;
-
- if ((handle >= 0) && (handle < pdp_pool_size)){
- if (p = pdp_pool[handle]) {
- /* mark_unused on a passing packet has no effect
- this is to support automatic conversion for passing packets
- so in order to delete a passing packet, it should be marked normal first */
- if (p->refloc){
- post("DEBUG: pdp_mark_unused called on a passing packet. ignored.");
- return;
- }
-
- /* decrease the refcount */
- if (p->users) {
- p->users--;
- //post("pdp_mark_unused: handle %d, users left %d", handle, p->users);
- }
- else {
- post("pdp_mark_unused: ERROR: handle %d has zero users (duplicate pdp_mark_unused ?)", handle);
- }
- }
- else {
- post("pdp_mark_unused: ERROR: invalid handle %d: no associated object", handle);
- }
- }
-
- else {
- /* -1 is the only invalid handle that doesn't trigger a warning */
- if (handle != -1) post("pdp_mark_unused: WARNING: invalid handle %d: out of bound", handle);
- }
-
-}
-
-/* mark a packet as unused, decreasing the reference count.
- if the reference count reaches zero, the packet is ready to be recycled
- by a new packet allocation. it is illegal to reference a packet with
- reference count == zero. if the reference count is not == 1, only readonly
- access is permitted. */
-
-void
-pdp_packet_mark_unused(int handle)
-{
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- _pdp_packet_mark_unused_nolock(handle);
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-}
-
-void
-pdp_packet_mark_unused_atomic(int *handle)
-{
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- _pdp_packet_mark_unused_nolock(*handle);
- *handle = -1;
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-}
-
-/* delete a packet. this is more than mark_unused:
- it actually removes any reference. can be used for
- some packet types that have "expensive" resources.
- usually this is up to the garbage collector to call. */
-
-void
-pdp_packet_delete(int handle)
-{
- t_pdp *header = pdp_packet_header(handle);
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
-
- /* check if it's a valid handle */
- if ((handle >= 0) && (handle < pdp_pool_size) && pdp_pool[handle]){
-
- /* mark it unused */
- _pdp_packet_mark_unused_nolock(handle);
-
- /* if no users, dealloc */
- if (!header->users){
- _pdp_packet_dealloc(header);
- pdp_pool[handle] = NULL;
- }
-
- /* print a warning if failed */
- else{
- post("WARNING: pdp_packet_delete: packet %d was not deleted. %d users remaining",
- handle, header->users);
- }
- }
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
-}
-
-
-/* this turns any packet into a normal (non-passing) packet */
-
-void
-pdp_packet_unmark_passing(int packet)
-{
- t_pdp* header = pdp_packet_header(packet);
- if (!header) return;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- header->refloc = 0;
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
-}
-
-
-/* this marks a packet as passing. this means it changes
- owner on first copy_ro or copy_rw. the previous owner is
- notified by setting the handler to -1. */
-
-void
-pdp_packet_mark_passing(int *phandle)
-{
- t_pdp* header = pdp_packet_header(*phandle);
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- if (header){
- if (header->refloc){
- post("pdp_packet_mark_passing: ERROR: duplicate mark_passing on packet %d", *phandle);
- }
- else if (1 != header->users){
- post("pdp_packet_mark_passing: ERROR: packet %d is not exclusively owned by caller, it has %d users", *phandle, header->users);
- }
- else {
- header->refloc = phandle;
- }
- }
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
-}
-
-
-/* public data access methods */
-
-t_pdp*
-pdp_packet_header(int handle)
-{
- if ((handle >= 0) && (handle < pdp_pool_size)) return pdp_pool[handle];
- else return 0;
-}
-
-void*
-pdp_packet_subheader(int handle)
-{
- t_pdp* header = pdp_packet_header(handle);
- if (!header) return 0;
- return (void *)(&header->info.raw);
-}
-
-void*
-pdp_packet_data(int handle)
-{
- t_pdp *h;
- if ((handle >= 0) && (handle < pdp_pool_size))
- {
- h = pdp_pool[handle];
- if (!h) return 0;
- return (char *)(h) + PDP_HEADER_SIZE;
- }
- else return 0;
-}
-
-
-/* OBSOLETE: use packet description */
-/* check if two packets are allocated and of the same type */
-bool pdp_packet_compat(int packet0, int packet1)
-{
-
- t_pdp *header0 = pdp_packet_header(packet0);
- t_pdp *header1 = pdp_packet_header(packet1);
-
- if (!(header1)){
- //post("pdp_type_compat: invalid header packet1");
- return 0;
- }
- if (!(header0)){
- //post("pdp_type_compat: invalid header packet 0");
- return 0;
- }
- if (header0->type != header1->type){
- //post("pdp_type_compat: types do not match");
- return 0;
- }
-
- return 1;
-}
-
-int pdp_packet_writable(int packet) /* returns true if packet is writable */
-{
- t_pdp *h = pdp_packet_header(packet);
- if (!h) return 0;
- return (h->users == 1);
-}
-
-void pdp_packet_replace_with_writable(int *packet) /* replaces a packet with a writable copy */
-{
- int new_p;
- if (!pdp_packet_writable(*packet)){
- new_p = pdp_packet_copy_rw(*packet);
- pdp_packet_mark_unused(*packet);
- *packet = new_p;
- }
-
-}
-
-/* pool stuff */
-
-int
-pdp_pool_collect_garbage(void)
-{
- t_pdp *p;
- int i;
- int nbpackets = pdp_packet_count;
-
- /* LOCK */
- pthread_mutex_lock(&pdp_pool_mutex);
-
- for (i=0; i < pdp_pool_size; i++){
- p = pdp_pool[i];
- if(p && !p->users) {
- _pdp_packet_dealloc(p);
- pdp_pool[i] = 0;
- }
- }
- nbpackets -= pdp_packet_count;
- //post("pdp_pool_collect_garbage: deleted %d unused packets", nbpackets);
-
- /* UNLOCK */
- pthread_mutex_unlock(&pdp_pool_mutex);
-
- return nbpackets;
-}
-
-void
-pdp_pool_set_max_mem_usage(int max)
-{
- if (max < 0) max = 0;
- pdp_packet_max_mem_usage = max;
-
-}
-
-
-
-
-
-
-/* malloc wrapper that calls garbage collector */
-void *pdp_alloc(int size)
-{
- void *ptr = malloc(size);
-
- //post ("malloc called for %d bytes", size);
-
- if (ptr) return ptr;
-
- post ("malloc failed in a pdp module: running garbage collector.");
-
- pdp_pool_collect_garbage();
- return malloc(size);
-}
-
-
-void pdp_dealloc(void *stuff)
-{
- free (stuff);
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_packet2.c b/system/kernel/pdp_packet2.c
deleted file mode 100644
index 3717a77..0000000
--- a/system/kernel/pdp_packet2.c
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Pure Data Packet system implementation: Packet Manager
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-
-#include <stdio.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <string.h>
-#include "pdp_post.h"
-#include "pdp_packet.h"
-#include "pdp_mem.h"
-#include "pdp_list.h"
-#include "pdp_type.h"
-#include "pdp_debug.h"
-
-
-/* packet implementation. contains class and packet (instance) handling
-
- some notes on packet operations.
- copy ro/rw and unregister are relatively straightforward
- packet creation can be done in 2 ways in this interface:
- create + reuse
- however, these methods should only be called by specific factory
- methods, so the user should only create packets using pdp_factory_newpacket
-
- reuse or create is thus the responsability of the factory methods for
- each packet type (class) implementation
-
-
-*/
-
-
-/* NOTE:
- the packet pool methods are called within the pool locks. this probably
- needs to change, because it will cause deadlocks for container packets (fobs) */
-
-
-/* new implementation: probably just a minor adjustment: add the reuse fifo attached
- to type desc symbol name
- need to check and possibly eliminate hacks for non-pure packets
-
- pdp_packet_new:
- LOCK
- 1. check reuse fifo
- 2. empty -> create packet+return (search array)
- 3. element -> check if type is correct, yes->pop+return, no->goto 1.
- UNLOCK
- 4. wakeup
-
- pdp_packet_mark_unused
-
- 1. check refcount. if > 1 dec + exit
- 2. if 1 put packet to sleep
- 3. dec refcount
- 4. add to reuse fifo (no fifo -> create)
-
- pdp_packet_delete: analogous to mark_unused
- pdp_packet_copy_ro/rw: analogous to new
-
-*/
-
-
-/* the pool */
-#define PDP_INITIAL_POOL_SIZE 64
-static int pdp_pool_size;
-static t_pdp** pdp_pool;
-
-/* mutex: protects the pool and reuse lists attached to symbols */
-static pthread_mutex_t pdp_pool_mutex;
-#define LOCK pthread_mutex_lock (&pdp_pool_mutex)
-#define UNLOCK pthread_mutex_unlock (&pdp_pool_mutex)
-
-/* the list of classes */
-static t_pdp_list *class_list;
-
-/* debug */
-void
-pdp_packet_print_debug(int packet)
-{
- t_pdp *h = pdp_packet_header(packet);
- pdp_post("debug info for packet %d", packet);
- if (!h){
- pdp_post("invalid packet");
- }
- else{
- pdp_post ("\ttype: %d", h->type);
- pdp_post ("\tdesc: %s", h->desc ? h->desc->s_name : "unknown");
- pdp_post ("\tsize: %d", h->size);
- pdp_post ("\tflags: %x", h->flags);
- pdp_post ("\tusers: %d", h->users);
- pdp_post ("\tclass: %x", h->theclass);
- }
-}
-
-
-
-/* setup methods */
-
-void
-pdp_packet_setup(void)
-{
-
- pdp_pool_size = PDP_INITIAL_POOL_SIZE;
- pdp_pool = (t_pdp **)pdp_alloc(PDP_INITIAL_POOL_SIZE * sizeof(t_pdp *));
- bzero(pdp_pool, pdp_pool_size * sizeof(t_pdp *));
- class_list = pdp_list_new(0);
- pthread_mutex_init(&pdp_pool_mutex, NULL);
-}
-
-/* class methods */
-t_pdp_class *pdp_class_new(t_pdp_symbol *type, t_pdp_factory_method create){
- t_pdp_class *c = (t_pdp_class *)pdp_alloc(sizeof(t_pdp_class));
- memset(c, 0, sizeof(t_pdp_class));
- c->create = create;
- c->type = type; // set type
- pdp_list_add(class_list, a_pointer, (t_pdp_word)((void *)c));
- return c;
-}
-
-/* the packet factory */
-int pdp_factory_newpacket(t_pdp_symbol *type)
-{
- int p;
- t_pdp_class *c;
- t_pdp_atom *a = class_list->first;
-
- /* try to reuse first
- THINK: should this be the responsability of the type specific constructors,
- or should a packet allways be reusable (solution: depends on what the cleanup method returns??)
- */
- p = pdp_packet_reuse(type);
- if (-1 != p) return p;
-
-
- /* call class constructor */
- while(a){
- c = (t_pdp_class *)(a->w.w_pointer);
- if (c->type && pdp_type_description_match(type, c->type)){
- //pdp_post("method %x, type %s", c->create, type->s_name);
- return (c->create) ? (*c->create)(type) : -1;
- }
- a = a->next;
- }
- return -1;
-}
-
-static void
-_pdp_pool_expand_nolock(void){
- int i;
-
- /* double the size */
- int new_pool_size = pdp_pool_size << 1;
- t_pdp **new_pool = (t_pdp **)pdp_alloc(new_pool_size * sizeof(t_pdp *));
- bzero(new_pool, new_pool_size * sizeof(t_pdp *));
- memcpy(new_pool, pdp_pool, pdp_pool_size * sizeof(t_pdp *));
- pdp_dealloc(pdp_pool);
- pdp_pool = new_pool;
- pdp_pool_size = new_pool_size;
-}
-
-
-
-
-/* private _pdp_packet methods */
-
-/* packets can only be created and destroyed using these 2 methods */
-/* it updates the mem usage and total packet count */
-
-static void
-_pdp_packet_dealloc_nolock(t_pdp *p)
-{
- /* free memory */
- pdp_dealloc (p);
-}
-
-static t_pdp*
-_pdp_packet_alloc_nolock(unsigned int datatype, unsigned int datasize)
-{
- unsigned int totalsize = datasize + PDP_HEADER_SIZE;
- t_pdp *p = (t_pdp *)pdp_alloc(totalsize);
- if (p){
- memset(p, 0, PDP_HEADER_SIZE); //initialize header to 0
- p->type = datatype;
- p->size = totalsize;
- p->users = 1;
- }
- return p;
-}
-
-
-/* create a new packet and expand pool if necessary */
-static int
-_pdp_packet_create_nolock(unsigned int datatype, unsigned int datasize)
-{
- int p = 0;
- while(1){
- for (; p < pdp_pool_size; p++){
- if (!pdp_pool[p]){
- /* found slot to store packet*/
- t_pdp *header = _pdp_packet_alloc_nolock(datatype, datasize);
- if (!header) return -1; // error allocating packet
- pdp_pool[p] = header;
- return p;
- }
- }
- /* no slot found, expand pool */
- _pdp_pool_expand_nolock();
- }
-}
-
-
-void
-pdp_packet_destroy(void)
-{
- int i = 0;
- /* dealloc all the data in object stack */
- pdp_post("DEBUG: pdp_packet_destroy: clearing object pool.");
- while ((i < pdp_pool_size) && (pdp_pool[i])) _pdp_packet_dealloc_nolock(pdp_pool[i++]);
-}
-
-
-
-
-
-
-
-
-/* public pool operations: have to be thread safe so each entry point
- locks the mutex */
-
-
-/* create a new packet.
- this should only be used by type specific factory methods, and only if the
- reuse method fails, since it will always create a new packet */
-int
-pdp_packet_create(unsigned int datatype, unsigned int datasize /*without header*/)
-{
- int packet;
- LOCK;
- packet = _pdp_packet_create_nolock(datatype, datasize);
- UNLOCK;
- return packet;
-}
-
-
-/* return a new packet.
- it tries to reuse a packet based on
- 1. matching data size
- 2. abscence of destructor (which SHOULD mean there are no enclosed references)
-
- it obviously can't use the reuse fifo tagged to a symbolic type description
-
- ALWAYS USE pdp_packet_reuse BEFORE calling pdp_packet_new if possible
- use both ONLY IN CONSTRUCTORS !!!
-
- use pdp_packet_factory to create packets as a "user"
-
- this is a summary of all internal packet creation mechanisms:
-
- -> pdp_packet_reuse, which uses symbolic type descriptions, and should work for all packet types
- it returns an initialized container (meta = correct, data = garbage)
-
- -> pdp_packet_new, which only works for non-pure packets, and reuses packets based on data type
- it returns a pure packet (meta + data = garbage)
-
- -> pdp_packet_create, like pdp_packet_new, only it always creates a new packet
-
-
-
-*/
-
-int
-pdp_packet_new(unsigned int datatype, unsigned int datasize)
-{
- t_pdp *header;
- int packet;
- LOCK;
- for (packet = 0; packet < pdp_pool_size; packet++){
- header = pdp_pool[packet];
- /* check data size */
- if (header
- && header->users == 0
- && header->size == datasize + PDP_HEADER_SIZE
- && !(header->theclass && header->theclass->cleanup)){
-
- /* ok, got one. initialize */
- memset(header, 0, PDP_HEADER_SIZE);
- header->users = 1;
- header->type = datatype;
- header->size = datasize + PDP_HEADER_SIZE;
-
- UNLOCK; //EXIT1
- return packet;
- }
- }
-
- /* no usable non-pure packet found, create a new one */
-
- UNLOCK; //EXIT2
- return pdp_packet_create(datatype, datasize);
-
-
-
-}
-
-
-/* internal method to add a packet to a packet type
- description symbol's unused packet fifo */
-void
-_pdp_packet_save_nolock(int packet)
-{
- t_pdp *header = pdp_packet_header(packet);
- t_pdp_symbol *s;
- PDP_ASSERT(header);
- PDP_ASSERT(header->users == 0);
- PDP_ASSERT(header->desc);
- s = header->desc;
- if (!s->s_reusefifo) s->s_reusefifo = pdp_list_new(0);
- pdp_list_add(s->s_reusefifo, a_packet, (t_pdp_word)packet);
-}
-
-/* this will revive a packet matching a certain type description
- no wildcards are allowed */
-int
-pdp_packet_reuse(t_pdp_symbol *type_description)
-{
- int packet = -1;
- t_pdp *header = 0;
- t_pdp_list *l = 0;
- LOCK;
- if (!type_description || !(l = type_description->s_reusefifo)) goto exit;
- while(l->elements){
- packet = pdp_list_pop(l).w_packet;
- header = pdp_packet_header(packet);
-
- /* check if reuse fifo is consistent (packet unused + correct type)
- packet could be deleted and replaced with another one, or
- revived without the index updated (it's a "hint cache") */
-
- if (header->users == 0){
- /* check if type matches */
- if (pdp_type_description_match(header->desc, type_description)){
- header->users++; // revive
- goto exit;
- }
- /* if not, add the packet to the correct reuse fifo */
- else{
- _pdp_packet_save_nolock(packet);
- }
- }
-
- /* remove dangling refs */
- header = 0;
- packet = -1;
- }
-
- exit:
- UNLOCK;
- if (header && header->theclass && header->theclass->wakeup){
- header->theclass->wakeup(header); // revive if necessary
- }
- return packet;
-}
-
-/* find all unused packets in pool, marked as used (to protect from other reapers)
- and return them as a list. non-pure packets are not revived */
-
-
-
-
-
-/* this returns a copy of a packet for read only access.
- (increases refcount of the packet -> packet will become readonly if it was
- writable, i.e. had rc=1 */
-
-int
-pdp_packet_copy_ro(int handle)
-{
- t_pdp* header;
-
- if (header = pdp_packet_header(handle)){
- PDP_ASSERT(header->users); // consistency check
- LOCK;
- header->users++; // increment reference count
- UNLOCK;
- }
- else handle = -1;
- return handle;
-}
-
-/* clone a packet: create a new packet with the same
- type as the source packet */
-
-int
-pdp_packet_clone_rw(int handle)
-{
- t_pdp* header;
- int new_handle = -1;
-
-
- if (header = pdp_packet_header(handle)){
- /* consistency checks */
- PDP_ASSERT(header->users);
- PDP_ASSERT(header->desc);
-
- /* first try to reuse old packet */
- new_handle = pdp_packet_reuse(header->desc);
-
- /* if this failed, create a new one using the central packet factory method */
- if (-1 == new_handle) new_handle = pdp_factory_newpacket(header->desc);
- }
-
- return new_handle;
-}
-
-/* return a copy of a packet (clone + copy data) */
-int
-pdp_packet_copy_rw(int handle)
-{
- t_pdp *header, *new_header;
- int new_handle = -1;
-
- if (!(header = pdp_packet_header(handle))) return -1;
-
- /* check if we are allowed to copy */
- if (header->flags & PDP_FLAG_DONOTCOPY) return -1;
-
- /* get target packet */
- new_handle = pdp_packet_clone_rw(handle);
- if (-1 == new_handle) return -1;
- new_header = pdp_packet_header(new_handle);
-
- /* if there is a copy method, use that one */
- if (header->theclass && header->theclass->copy){
- header->theclass->copy(header, new_header);
- }
-
- /* otherwize copy the data verbatim */
- else {
- memcpy(pdp_packet_data(new_handle),
- pdp_packet_data(handle),
- pdp_packet_data_size(handle));
- }
-
- return new_handle;
-
-}
-
-
-/* decrement refcount */
-void pdp_packet_mark_unused(int handle)
-{
- t_pdp *header;
- if (!(header = pdp_packet_header(handle))) return;
-
- PDP_ASSERT(header->users); // consistency check
-
- LOCK;
-
- /* just decrement refcount */
- if (header->users > 1){
- header->users--;
- }
-
- /* put packet to sleep if refcount 1->0 */
- else {
- if (header->theclass && header->theclass->sleep){
- /* call sleep method (if any) outside of lock
- while the packet is still alive, so it won't be
- acclaimed by another thread */
- UNLOCK;
- header->theclass->sleep(header);
- LOCK;
- }
- /* clear refcount & save in fifo for later use */
- header->users = 0;
- if (header->desc) // sleep could have destructed packet..
- _pdp_packet_save_nolock(handle);
- }
-
- UNLOCK;
-}
-
-
-
-/* delete a packet. rc needs to be == 1 */
-void pdp_packet_delete(int handle)
-{
- t_pdp *header;
- header = pdp_packet_header(handle);
- PDP_ASSERT(header);
- PDP_ASSERT(header->users == 1); // consistency check
-
- LOCK;
-
- if (header->theclass && header->theclass->cleanup){
- /* call cleanup method (if any) outside of lock
- while the packet is still alive, so it won't be
- acclaimed by another thread */
- UNLOCK;
- header->theclass->cleanup(header);
- LOCK;
- }
-
- /* delete the packet */
- pdp_pool[handle] = 0;
- _pdp_packet_dealloc_nolock(header);
-
-
- UNLOCK;
-}
-
-
-
-
-
-
-
-/* public data access methods */
-
-t_pdp*
-pdp_packet_header(int handle)
-{
- if ((handle >= 0) && (handle < pdp_pool_size)) return pdp_pool[handle];
- else return 0;
-}
-
-void*
-pdp_packet_subheader(int handle)
-{
- t_pdp* header = pdp_packet_header(handle);
- if (!header) return 0;
- return (void *)(&header->info.raw);
-}
-
-void*
-pdp_packet_data(int handle)
-{
- t_pdp *h;
- if ((handle >= 0) && (handle < pdp_pool_size))
- {
- h = pdp_pool[handle];
- if (!h) return 0;
- return (char *)(h) + PDP_HEADER_SIZE;
- }
- else return 0;
-}
-
-int
-pdp_packet_data_size(int handle)
-{
- t_pdp *h;
- if ((handle >= 0) && (handle < pdp_pool_size))
- {
- h = pdp_pool[handle];
- if (!h) return 0;
- return h->size - PDP_HEADER_SIZE;
- }
- else return 0;
-}
-
-
-
-
-int pdp_packet_writable(int packet) /* returns true if packet is writable */
-{
- t_pdp *h = pdp_packet_header(packet);
- if (!h) return 0;
- return (h->users == 1);
-}
-
-void pdp_packet_replace_with_writable(int *packet) /* replaces a packet with a writable copy */
-{
- int new_p;
- if (!pdp_packet_writable(*packet)){
- new_p = pdp_packet_copy_rw(*packet);
- pdp_packet_mark_unused(*packet);
- *packet = new_p;
- }
-
-}
-
-/* pool stuff */
-
-int
-pdp_pool_collect_garbage(void)
-{
- pdp_post("ERROR: garbage collector not implemented");
- return 0;
-}
-
-void
-pdp_pool_set_max_mem_usage(int max)
-{
- pdp_post("ERROR: mem limit not implemented");
-}
-
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_post.c b/system/kernel/pdp_post.c
deleted file mode 100644
index fb761d0..0000000
--- a/system/kernel/pdp_post.c
+++ /dev/null
@@ -1,48 +0,0 @@
-
-/*
- * Pure Data Packet system file. pdp logging.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include "pdp_post.h"
-
-/* list printing should be moved here too */
-
-/* write a message to log (console) */
-void pdp_post_n(char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-}
-void pdp_post(char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- putc('\n', stderr);
-}
-
-
diff --git a/system/kernel/pdp_queue.c b/system/kernel/pdp_queue.c
deleted file mode 100644
index 665a236..0000000
--- a/system/kernel/pdp_queue.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Pure Data Packet - processor queue module.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-
-/*
- this is a the processor queue pdp system module
- it receives tasks from objects that are schedules to
- be computed in another thread. the object is signalled back
- when the task is completed.
-
- this is not a standard pd class. it is a sigleton class
- using a standard pd clock to poll for compleded methods on
- every scheduler run. this is a hack to do thread synchronization
- in a thread unsafe pd.
-
- the queue object can be reused. the pdp system however only
- has one instance (one pdp queue. pdp remains a serial program.)
-
- */
-
-#include "pdp.h"
-#include <pthread.h>
-#include <unistd.h>
-#include <stdio.h>
-
-
-#define D if (0)
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#define PDP_QUEUE_LOGSIZE 10
-#define PDP_QUEUE_DELTIME 10.0f
-
-
-
-
-/********************* general purpose pd process queue class *********************/
-
-void pdp_procqueue_wait(t_pdp_procqueue *q)
-{
- D post("pdp_procqueue_wait(%x): waiting for pdp_queue_thread to finish processing", q);
- pthread_mutex_lock(&q->mut);
- while(((q->curr - q->head) & q->mask) != 0){
-
- pthread_cond_wait(&q->cond_processingdone, &q->mut);
- }
- pthread_mutex_unlock(&q->mut);
- D post("pdp_procqueue_wait(%x): pdp_procqueue_thread has finished processing", q);
-
-}
-void pdp_procqueue_finish(t_pdp_procqueue *q, int index)
-{
-
- if (-1 == index) {
- //post("pdp_pq_remove: index == -1");
- return;
- }
- /* wait for processing thread to finish*/
- pdp_procqueue_wait(q);
-
- /* invalidate callback at index */
- q->q[index & q->mask].x_callback = 0;
- q->q[index & q->mask].x_queue_id = 0;
-
-}
-
-static void pdp_procqueue_signal_processor(t_pdp_procqueue *q)
-{
-
- //NOTE: uncommenting these post statements causes a libc crash
- //in mutex lock in putc
- //D post("pdp_procqueue_signal_processor(%x): signalling process thread", q);
- pthread_mutex_lock(&q->mut);
- pthread_cond_signal(&q->cond_dataready);
- pthread_mutex_unlock(&q->mut);
- //D post("pdp_procqueue_signal_processor(%x): signalling done", q);
-
-
-}
-
-static void pdp_procqueue_wait_for_feeder(t_pdp_procqueue *q)
-{
-
-
- /* only use locking when there is no data */
- if(((q->curr - q->head) & q->mask) == 0){
-
- /* signal processing done */
- D post("pdp_procqueue_wait_for_feeder(%x): signalling processing is done", q);
- pthread_mutex_lock(&q->mut);
- pthread_cond_signal(&q->cond_processingdone);
-
- /* wait until there is an item in the queue */
- while(((q->curr - q->head) & q->mask) == 0){
- pthread_cond_wait(&q->cond_dataready, &q->mut);
- }
-
- pthread_mutex_unlock(&q->mut);
- D post("pdp_procqueue_wait_for_feeder(%x): waiting done", q);
-
- }
-}
-
-void pdp_procqueue_add(t_pdp_procqueue *q, void *owner, void *process, void *callback, int *queue_id)
-{
- int i;
-
- /* if processing is in not in thread, just call the funcs */
- if (!q->use_thread){
- D post("pdp_procqueue_add(%q): calling processing routine directly", q);
- if (queue_id) *queue_id = -1;
- if (process) ((t_pdpmethod) process)(owner);
- if (callback) ((t_pdpmethod) callback)(owner);
- return;
- }
-
-
- /* if queue is full, call directly */
- if (1 == ((q->tail - q->head) & q->mask)) {
- //post("pdp_procqueue_add: WARNING: processing queue (%x) is full.\n", q);
- //post("pdp_procqueue_add: WARNING: tail %x, head %x, mask %x.\n", q->tail, q->head, q->mask);
- //post("pdp_procqueue_add: WARNING: skipping process method, calling callback directly.\n");
- if (queue_id) *queue_id = -1;
- if (callback) ((t_pdpmethod) callback)(owner);
- return;
- //exit(1);
- }
-
- /* schedule method in thread queue */
- i = q->head & q->mask;
- q->q[i].x_owner = owner;
- q->q[i].x_process = process;
- q->q[i].x_callback = callback;
- q->q[i].x_queue_id = queue_id;
- if (queue_id) *queue_id = i;
- //post("pdp_queue_add: added method to queue, index %d", i);
-
-
- // increase the packet count
- q->packets++;
-
- // move head forward
- q->head++;
-
- pdp_procqueue_signal_processor(q);
-
-}
-
-
-/* processing thread */
-static void *pdp_procqueue_thread(void *vq)
-{
- t_pdp_procqueue *q = (t_pdp_procqueue *)vq;
-
- D post("pdp_procqueue_thread(%x): thread started", q);
-
- while(1){
- t_process_queue_item *p;
-
-
- D post("pdp_procqueue_thread(%x): waiting for feeder", q);
-
- /* wait until there is data available */
- pdp_procqueue_wait_for_feeder(q);
-
-
- D post("pdp_procqueue_thread(%x): processing %d", q, q->curr & q->mask);
-
-
- /* call the process routine */
- p = &q->q[q->curr & q->mask];
- if (p->x_process)
- (p->x_process)(p->x_owner);
-
- /* advance */
- q->curr++;
-
-
- }
-}
-
-
-/* call back all the callbacks */
-static void pdp_procqueue_callback (t_pdp_procqueue *q)
-{
-
- /* call callbacks for finished packets */
- while(0 != ((q->curr - q->tail) & q->mask))
- {
- int i = q->tail & q->mask;
- /* invalidate queue id */
- if(q->q[i].x_queue_id) *q->q[i].x_queue_id = -1;
- /* call callback */
- if(q->q[i].x_callback) (q->q[i].x_callback)(q->q[i].x_owner);
- //else post("pdp_pq_tick: callback %d is disabled",i );
- q->tail++;
- }
-
-}
-
-/* the clock method */
-static void pdp_procqueue_tick (t_pdp_procqueue *q)
-{
- /* do work */
- //if (!(ticks % 1000)) post("pdp tick %d", ticks);
-
- if (!q->use_thread) return;
-
- /* call callbacks */
- pdp_procqueue_callback(q);
-
- /* increase counter */
- q->ticks++;
-
- /* set clock for next update */
- clock_delay(q->pdp_clock, q->deltime);
-}
-
-
-
-void pdp_procqueue_use_thread(t_pdp_procqueue* q, int t)
-{
- /* if thread usage is being disabled,
- wait for thread to finish processing first */
- if (t == 0) {
- pdp_procqueue_wait(q);
- q->use_thread = 0;
- pdp_procqueue_callback(q);
- clock_unset(q->pdp_clock);
- }
- else {
- clock_unset(q->pdp_clock);
- clock_delay(q->pdp_clock, q->deltime);
- q->use_thread = 1;
- }
-
-}
-
-void pdp_procqueue_init(t_pdp_procqueue *q, double milliseconds, int logsize)
-{
- pthread_attr_t attr;
- int size = 1 << logsize;
-
- /* setup pdp queue processor object */
- q->ticks = 0;
- q->deltime = milliseconds;
-
- /* setup queue data */
- q->mask = size - 1;
- q->head = 0;
- q->tail = 0;
- q->curr = 0;
- q->q = pdp_alloc(size * sizeof(t_process_queue_item));
- memset(q->q, 0, size * sizeof(t_process_queue_item));
-
- /* enable threads */
- q->use_thread = 1;
-
- /* setup synchro stuff */
- pthread_mutex_init(&q->mut, NULL);
- pthread_cond_init(&q->cond_dataready, NULL);
- pthread_cond_init(&q->cond_processingdone, NULL);
-
-
- /* allocate the clock */
- q->pdp_clock = clock_new(q, (t_method)pdp_procqueue_tick);
-
- /* set the clock */
- clock_delay(q->pdp_clock, 0);
-
- /* start processing thread */
-
- /* glibc doc says SCHED_OTHER is default,
- but it seems not to be when initiated from a RT thread
- so we explicitly set it here */
- pthread_attr_init (&attr);
- //pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
- pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
-
- D post("pdp_procqueue_init(%x): starting thread", q);
- pthread_create(&q->thread_id, &attr, pdp_procqueue_thread, (void *)q);
- D post("pdp_procqueue_init(%x): back in pd thread", q);
-
- /* wait for processing thread to finish */
- //pdp_procqueue_wait(q);
-
- /* set default disable/enable thread here */
- //post("pdp_queue: THREAD PROCESSING ON BY DEFAULT!!");
- pdp_procqueue_use_thread(q,0);
-
-}
-
-
-
-
-/* the (static) pdp queue object */
-static t_pdp_procqueue pdp_queue;
-
-
-/* get the default queue */
-t_pdp_procqueue *pdp_queue_get_queue(void){return &pdp_queue;}
-
-
-#if 1
-/* default pdp queue shortcut methods */
-void pdp_queue_wait() {pdp_procqueue_wait(&pdp_queue);}
-void pdp_queue_finish(int index) { pdp_procqueue_finish(&pdp_queue, index);}
-void pdp_queue_add(void *owner, void *process, void *callback, int *queue_id) {
- pdp_procqueue_add(&pdp_queue, owner, process, callback, queue_id);
-}
-void pdp_queue_use_thread(int t) {pdp_procqueue_use_thread(&pdp_queue, t);}
-void pdp_queue_setup(void){
- pdp_procqueue_init(&pdp_queue, PDP_QUEUE_DELTIME, PDP_QUEUE_LOGSIZE);
- pdp_procqueue_use_thread(&pdp_queue,0);
-}
-#endif
-
-
-
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/system/kernel/pdp_symbol.c b/system/kernel/pdp_symbol.c
deleted file mode 100644
index 32e9e33..0000000
--- a/system/kernel/pdp_symbol.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Pure Data Packet system implementation. : code implementing pdp's namespace (symbols)
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <string.h>
-#include <pthread.h>
-#include "pdp_symbol.h"
-#include "pdp_list.h"
-#include "pdp_debug.h"
-
-// some extra prototypes
-void *pdp_alloc(int size);
-void pdp_dealloc(void *data);
-
-// the symbol hash mutex
-static pthread_mutex_t pdp_hash_mutex;
-
-#define HASHSIZE 1024
-static t_pdp_symbol *pdp_symhash[HASHSIZE];
-
-
-#define LOCK pthread_mutex_lock(&pdp_hash_mutex)
-#define UNLOCK pthread_mutex_unlock(&pdp_hash_mutex)
-
-
-static void _pdp_symbol_init(t_pdp_symbol *s)
-{
- memset(s, 0, sizeof(*s));
- s->s_forth.t = a_undef;
-}
-
-
-/* shamelessly copied from pd src and made thread safe */
-t_pdp_symbol *_pdp_dogensym(char *s, t_pdp_symbol *oldsym)
-{
- t_pdp_symbol **sym1, *sym2;
- unsigned int hash1 = 0, hash2 = 0;
- int length = 0;
- char *s2 = s;
- while (*s2)
- {
- hash1 += *s2;
- hash2 += hash1;
- length++;
- s2++;
- }
- sym1 = pdp_symhash + (hash2 & (HASHSIZE-1));
-
- /* lock hash */
- LOCK;
-
- while (sym2 = *sym1)
- {
- if (!strcmp(sym2->s_name, s)) goto gotit;
- sym1 = &sym2->s_next;
- }
- if (oldsym){
- sym2 = oldsym;
- }
- else
- {
- sym2 = (t_pdp_symbol *)pdp_alloc(sizeof(*sym2));
- _pdp_symbol_init(sym2);
- sym2->s_name = pdp_alloc(length+1);
- sym2->s_next = 0;
- strcpy(sym2->s_name, s);
- }
- *sym1 = sym2;
-
- gotit:
-
- /* unlock hash */
- UNLOCK;
- return (sym2);
-}
-
-t_pdp_symbol *pdp_gensym(char *s)
-{
- return(_pdp_dogensym(s, 0));
-}
-
-
-/* connect a parsed typelist to a symbol type name
- 1 = succes, 0 = error (symbol already connected) */
-int pdp_symbol_set_typelist(t_pdp_symbol *s, t_pdp_list *typelist)
-{
- int status = 0;
- LOCK;
- if (!s->s_type){
- s->s_type = typelist;
- status = 1;
- }
- UNLOCK;
- return status;
-}
-
-
-void pdp_symbol_apply_all(t_pdp_symbol_iterator it)
-{
- int i;
- for (i=0; i<HASHSIZE; i++){
- t_pdp_symbol *s;
- for (s = pdp_symhash[i]; s; s=s->s_next){
- it(s);
- }
-
- }
-}
-
-t_pdp_symbol _pdp_sym_wildcard;
-t_pdp_symbol _pdp_sym_float;
-t_pdp_symbol _pdp_sym_int;
-t_pdp_symbol _pdp_sym_symbol;
-t_pdp_symbol _pdp_sym_packet;
-t_pdp_symbol _pdp_sym_pointer;
-t_pdp_symbol _pdp_sym_invalid;
-t_pdp_symbol _pdp_sym_list;
-t_pdp_symbol _pdp_sym_question_mark;
-t_pdp_symbol _pdp_sym_atom;
-t_pdp_symbol _pdp_sym_null;
-t_pdp_symbol _pdp_sym_quote_start;
-t_pdp_symbol _pdp_sym_quote_end;
-t_pdp_symbol _pdp_sym_return;
-t_pdp_symbol _pdp_sym_nreturn;
-t_pdp_symbol _pdp_sym_defstart;
-t_pdp_symbol _pdp_sym_defend;
-t_pdp_symbol _pdp_sym_if;
-t_pdp_symbol _pdp_sym_then;
-t_pdp_symbol _pdp_sym_local;
-t_pdp_symbol _pdp_sym_forth;
-t_pdp_symbol _pdp_sym_call;
-t_pdp_symbol _pdp_sym_push;
-t_pdp_symbol _pdp_sym_pop;
-
-static void _sym(char *name, t_pdp_symbol *s)
-{
- t_pdp_symbol *realsym;
- _pdp_symbol_init(s);
- s->s_name = name;
- realsym = _pdp_dogensym(name, s);
- PDP_ASSERT(realsym == s); // if this fails, the symbol was already defined
-}
-
-void pdp_symbol_setup(void)
-{
- // create mutexes
- pthread_mutex_init(&pdp_hash_mutex, NULL);
-
- // init symbol hash
- memset(pdp_symhash, 0, HASHSIZE * sizeof(t_pdp_symbol *));
-
- // setup predefined symbols (those that have direct pointer access for speedup)
- _sym("*", &_pdp_sym_wildcard);
- _sym("float", &_pdp_sym_float);
- _sym("int", &_pdp_sym_int);
- _sym("symbol", &_pdp_sym_symbol);
- _sym("packet", &_pdp_sym_packet);
- _sym("pointer", &_pdp_sym_pointer);
- _sym("invalid", &_pdp_sym_invalid);
- _sym("list", &_pdp_sym_list);
- _sym("?", &_pdp_sym_question_mark);
- _sym("atom", &_pdp_sym_atom);
- _sym("null", &_pdp_sym_null);
- _sym("[", &_pdp_sym_quote_start);
- _sym("]", &_pdp_sym_quote_end);
- _sym("ret", &_pdp_sym_return);
- _sym("nret", &_pdp_sym_nreturn);
- _sym(":", &_pdp_sym_defstart);
- _sym(";", &_pdp_sym_defend);
- _sym("if", &_pdp_sym_if);
- _sym("then", &_pdp_sym_then);
- _sym("local", &_pdp_sym_local);
- _sym("forth", &_pdp_sym_forth);
- _sym("call", &_pdp_sym_call);
- _sym("push", &_pdp_sym_push);
- _sym("pop", &_pdp_sym_pop);
-
-}
-
-
diff --git a/system/kernel/pdp_type.c b/system/kernel/pdp_type.c
deleted file mode 100644
index c220269..0000000
--- a/system/kernel/pdp_type.c
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Pure Data Packet system implementation. : code for handling different packet types
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-/* this file contains type handling routines */
-
-#include <stdarg.h>
-#include <string.h>
-#include <pthread.h>
-#include "pdp.h"
-
-
-// debug
-#define D if (0)
-
-
-static t_pdp_list *conversion_list;
-
-#define INIT_MAX_CACHE_SIZE 32
-
-static t_pdp_list *cached_conversion_list;
-static int max_cache_size;
-
-/* mutex */
-static pthread_mutex_t pdp_hash_mutex;
-static pthread_mutex_t pdp_conversion_mutex;
-static pthread_mutex_t pdp_cache_mutex;
-
-#define HASHSIZE 1024
-static t_pdp_symbol *pdp_symhash[HASHSIZE];
-
-
-/* shamelessly copied from pd src and made thread safe */
-t_pdp_symbol *_pdp_dogensym(char *s, t_pdp_symbol *oldsym)
-{
- t_pdp_symbol **sym1, *sym2;
- unsigned int hash1 = 0, hash2 = 0;
- int length = 0;
- char *s2 = s;
- while (*s2)
- {
- hash1 += *s2;
- hash2 += hash1;
- length++;
- s2++;
- }
- sym1 = pdp_symhash + (hash2 & (HASHSIZE-1));
-
- /* lock hash */
- pthread_mutex_lock(&pdp_hash_mutex);
-
- while (sym2 = *sym1)
- {
- if (!strcmp(sym2->s_name, s)) goto gotit;
- sym1 = &sym2->s_next;
- }
- if (oldsym) sym2 = oldsym;
- else
- {
- sym2 = (t_pdp_symbol *)pdp_alloc(sizeof(*sym2));
- sym2->s_name = pdp_alloc(length+1);
- _pdp_symbol_clear_namespaces(sym2);
- sym2->s_next = 0;
- strcpy(sym2->s_name, s);
- }
- *sym1 = sym2;
-
- gotit:
-
- /* unlock hash */
- pthread_mutex_unlock(&pdp_hash_mutex);
- return (sym2);
-}
-
-t_pdp_symbol *pdp_gensym(char *s)
-{
- return(_pdp_dogensym(s, 0));
-}
-
-/* convert a type to a list */
-t_pdp_list *pdp_type_to_list(t_pdp_symbol *type)
-{
- char *c = type->s_name;
- char *lastname = c;
- char tmp[100];
- int n = 0;
- t_pdp_list *l = pdp_list_new(0);
-
- while(*c){
- if (*c == '/'){
- strncpy(tmp, lastname, n);
- tmp[n] = 0;
- pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(tmp));
- c++;
- lastname = c;
- n = 0;
- }
- else{
- c++;
- n++;
- }
- }
- pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(lastname));
-
- return l;
-}
-
-
-/* get the description symbol. this includes some compat transition stuff with a warning */
-t_pdp_symbol *pdp_packet_get_description(int packet)
-{
- t_pdp *header = pdp_packet_header(packet);
-
- if (!header) return pdp_gensym("invalid");
- else if (!header->desc){
-
- post("ERROR: pdp_packet_get_description: packet %d has no description.", packet);
- pdp_packet_print_debug(packet);
- return pdp_gensym("unknown");
- }
- else return header->desc;
-}
-
-
-
-/* this runs a conversion program */
-int _pdp_type_run_conversion_program(t_pdp_conversion_program *program,
- int packet, t_pdp_symbol *dest_template)
-{
- /* run a conversion program:
- treat the source packet as readonly, and cleanup intermediates, such
- that the net result is the production of a new packet, with the
- source packet intact. */
-
- int p, tmp;
- t_pdp_atom *a;
- t_pdp_conversion_method m;
-
- // run the first line of the program
- a = program->first;
- m = a->w.w_pointer;
- D post("DEBUG: _pdp_type_run_conversion_program: method = %x", m);
- p = m(packet, dest_template);
- D post("DEBUG: _pdp_type_run_conversion_program: packet returned = %d, type = %s", p, pdp_packet_get_description(p)->s_name);
-
- // run the remaining lines + cleanup intermediates
- for (a=a->next; a; a=a->next){
- m = a->w.w_pointer;
- D post("DEBUG: _pdp_type_run_conversion_program: next method ptr = %x", m);
- tmp = m(p, dest_template);
- pdp_packet_mark_unused(p);
- p = tmp;
- }
- return p;
-}
-
-
-/* find a conversion program */
-t_pdp_conversion_program *
-_pdp_type_find_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern)
-{
- t_pdp_conversion *c;
- t_pdp_atom *a;
- t_pdp_conversion_program *retval = 0;
-
- /* lock conversion list */
- pthread_mutex_lock(&pdp_conversion_mutex);
-
- for (a = conversion_list->first; a; a=a->next){
- c = a->w.w_pointer;
- /* can be a wildcard match */
- if (pdp_type_description_match(src_pattern, c->src_pattern) &&
- pdp_type_description_match(dst_pattern, c->dst_pattern)) {
- /* found a program */
- D post("DEBUG: _pdp_type_find_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name);
- retval = c->program;
- goto gotit;
- }
- }
-
- /* no conversion program was found */
- retval = 0;
- gotit:
-
- /* lock conversion list */
- pthread_mutex_unlock(&pdp_conversion_mutex);
- return retval;
-}
-
-/* find a cached conversion program
- if one is found it will be moved to the back of the queue (MRU) */
-t_pdp_conversion_program *
-_pdp_type_find_cached_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern)
-{
- t_pdp_conversion *c, *c_tmp;
- t_pdp_atom *a;
- t_pdp_conversion_program *retval = 0;
-
- /* lock cached list */
- pthread_mutex_lock(&pdp_cache_mutex);
-
- for (a = cached_conversion_list->first; a; a=a->next){
- c = a->w.w_pointer;
- /* must be exact match */
- if ((src_pattern == c->src_pattern) &&
- (dst_pattern == c->dst_pattern)) {
-
- /* found a program */
- D post("DEBUG: _pdp_type_find_cached_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name);
- retval = c->program;
-
- /* make MRU (move to back) */
- c_tmp = cached_conversion_list->last->w.w_pointer;
- cached_conversion_list->last->w.w_pointer = c;
- a->w.w_pointer = c_tmp;
- goto gotit;
- }
- }
-
- retval = 0;
-
- gotit:
-
-
- /* un lock cached list */
- pthread_mutex_unlock(&pdp_cache_mutex);
-
- /* no conversion program was found */
- return retval;
-}
-
-
-/* conversion program manipulations */
-void pdp_conversion_program_free(t_pdp_conversion_program *program)
-{
- pdp_list_free(program);
-}
-
-/* debug print */
-void _pdp_conversion_program_print(t_pdp_conversion_program *program)
-{
- post("_pdp_conversion_program_print %x", program);
- pdp_list_print(program);
-}
-
-t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...)
-{
- t_pdp_conversion_program *p = pdp_list_new(0);
- t_pdp_conversion_method m = method;
- va_list ap;
-
- D post("DEBUG: pdp_conversion_program_new:BEGIN");
-
- pdp_list_add_back_pointer(p, m);
- va_start(ap, method);
- while (m = va_arg(ap, t_pdp_conversion_method)) pdp_list_add_back_pointer(p, m);
- va_end(ap);
-
- D post("DEBUG: pdp_conversion_program_new:END");
-
- return p;
-}
-
-t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program)
-{
- if (program) return pdp_list_copy(program);
- else return 0;
-}
-
-void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail)
-{
- return pdp_list_cat(program, tail);
-}
-
-/* conversion registration */
-void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program)
-{
- t_pdp_conversion *c = (t_pdp_conversion *)pdp_alloc(sizeof(*c));
- c->src_pattern = src_pattern;
- c->dst_pattern = dst_pattern;
- c->program = program;
-
- /* lock conversion list */
- pthread_mutex_lock(&pdp_conversion_mutex);
-
- pdp_list_add_back_pointer(conversion_list, c);
-
- /* unlock conversion list */
- pthread_mutex_unlock(&pdp_conversion_mutex);
-
-}
-
-/* register a cached conversion */
-void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program)
-{
-
- /* create the new conversion */
- t_pdp_conversion *c = (t_pdp_conversion *)pdp_alloc(sizeof(*c));
- c->src_pattern = src_pattern;
- c->dst_pattern = dst_pattern;
- c->program = program;
-
- /* lock cached conversion list */
- pthread_mutex_lock(&pdp_cache_mutex);
-
- /* check size, and remove LRU (top) if the cache is full */
- while (cached_conversion_list->elements >= max_cache_size){
- t_pdp_conversion *c_old = pdp_list_pop(cached_conversion_list).w_pointer;
- if (c_old->program) pdp_conversion_program_free(c_old->program);
- pdp_dealloc(c_old);
- }
-
- /* add and make MRU (back) */
- pdp_list_add_back_pointer(cached_conversion_list, c);
-
- /* unlock cached conversion list */
- pthread_mutex_unlock(&pdp_cache_mutex);
-}
-
-/* convert a given packet to a certain type (template) */
-int _pdp_packet_convert(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
- t_pdp_symbol *tmp_type = 0;
- int tmp_packet = -1;
-
- t_pdp_conversion_program *program = 0;
- t_pdp_conversion_program *program_last = 0;
- t_pdp_conversion_program *program_tail = 0;
-
- /* check if there is a program in the cached list, if so run it */
- if (program = _pdp_type_find_cached_conversion_program(type, dest_template))
- return _pdp_type_run_conversion_program(program, packet, dest_template);
-
- /* if it is not cached, iteratively convert
- and save program on top of cache list if a conversion path (program) was found */
-
- // run first conversion that matches
- program = pdp_conversion_program_copy(_pdp_type_find_conversion_program(type, dest_template));
- program_last = program;
- if (!program){
- D post("DEBUG: pdp_type_convert: (1) can't convert %s to %s", type->s_name, dest_template->s_name);
- return -1;
- }
- tmp_packet = _pdp_type_run_conversion_program(program, packet, dest_template);
- tmp_type = pdp_packet_get_description(tmp_packet);
-
- // run more conversions if necessary, deleting intermediate packets
- while (!pdp_type_description_match(tmp_type, dest_template)){
- int new_packet;
- program_tail = _pdp_type_find_conversion_program(tmp_type, dest_template);
- if (!program_tail){
- D post("DEBUG: pdp_type_convert: (2) can't convert %s to %s", tmp_type->s_name, dest_template->s_name);
- pdp_packet_mark_unused(tmp_packet);
- pdp_conversion_program_free(program);
- return -1;
- }
- if (program_last == program_tail){
- post("ERROR: pdp_packet_convert: conversion loop detected");
- }
- program_last = program_tail;
-
- pdp_conversion_program_add(program, program_tail);
- new_packet = _pdp_type_run_conversion_program(program_tail, tmp_packet, dest_template);
- pdp_packet_mark_unused(tmp_packet);
- tmp_packet = new_packet;
- tmp_type = pdp_packet_get_description(tmp_packet);
- }
-
- // save the conversion program
- pdp_type_register_cached_conversion(type, dest_template, program);
-
- // return resulting packet
- return tmp_packet;
-
-}
-
-/* convert or copy ro */
-int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
-
- /* if it is compatible, return a ro copy */
- if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_ro(packet);
-
- /* if not, convert to a new type */
- else return _pdp_packet_convert(packet, dest_template);
-}
-
-/* convert or copy rw */
-int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
-
- /* if it is compatible, just return a rw copy */
- if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_rw(packet);
-
- /* if not, convert to a new type */
- else return _pdp_packet_convert(packet, dest_template);
-}
-
-
-static void _setup_type_cache(t_pdp_symbol *s)
-{
- t_pdp_list *l = pdp_type_to_list(s);
- pthread_mutex_lock(&pdp_hash_mutex); //lock to prevent re-entry
- if (!s->s_type){
- s->s_type = l;
- l = 0;
- }
- pthread_mutex_unlock(&pdp_hash_mutex);
- if (l) pdp_list_free(l);
-}
-
-/* check if a type description fits a template
- this function is symmetric */
-int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern)
-{
- int retval = 0;
-
- t_pdp_atom *ad, *ap;
- t_pdp_symbol *wildcard = pdp_gensym("*");
-
-
- if (!(pattern)) post("PANICA");
- if (!(description)) post("PANICB");
-
-
- /* same type -> match */
- if (description == pattern) {retval = 1; goto done;}
-
- /* use the description list stored in the symbol for comparison */
- if (!(description->s_type)) _setup_type_cache(description);
- if (!(pattern->s_type)) _setup_type_cache(pattern);
-
- if (!(pattern->s_type)) post("PANIC1");
- if (!(description->s_type)) post("PANIC2");
-
- /* check size */
- if (description->s_type->elements != pattern->s_type->elements){retval = 0; goto done;}
-
- /* compare symbols of type list */
- for(ad=description->s_type->first, ap=pattern->s_type->first; ad; ad=ad->next, ap=ap->next){
- if (ad->w.w_symbol == wildcard) continue;
- if (ap->w.w_symbol == wildcard) continue;
- if (ad->w.w_symbol != ap->w.w_symbol) {retval = 0; goto done;} /* difference and not a wildcard */
- }
-
- /* type templates match */
- retval = 1;
-
- done:
- D post("DEBUG: testing match between %s and %s: %s",
- description->s_name, pattern->s_name, retval ? "match" : "no match");
- return retval;
-
-}
-
-
-
-
-
-/* setup method */
-void pdp_type_setup(void)
-{
- int i;
-
- // create mutexes
- pthread_mutex_init(&pdp_hash_mutex, NULL);
- pthread_mutex_init(&pdp_conversion_mutex, NULL);
- pthread_mutex_init(&pdp_cache_mutex, NULL);
-
- // init symbol hash
- memset(pdp_symhash, 0, HASHSIZE * sizeof(t_pdp_symbol *));
-
- // create conversion lists
- cached_conversion_list = pdp_list_new(0);
- conversion_list = pdp_list_new(0);
- max_cache_size = INIT_MAX_CACHE_SIZE;
-
-
-
-
-}
diff --git a/system/kernel/pdp_type.c_old b/system/kernel/pdp_type.c_old
deleted file mode 100644
index 4e42d53..0000000
--- a/system/kernel/pdp_type.c_old
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Pure Data Packet system implementation. : code for handling different packet types
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-/* this file contains type handling routines
- note: pd symbols are used for type identification
- for porting to other hosts, i suggest reimplementing t_pdp_symbol */
-
-// debug
-
-#include <fnmatch.h>
-#include <stdarg.h>
-#include <string.h>
-#include <pthread.h>
-#include "pdp.h"
-
-/*
-
-
-
-*/
-
-
-#define D if (0)
-
-
-static t_pdp_conversion *conversion_list;
-
-#define CACHE_SIZE 32
-static t_pdp_conversion *cached_conversion_list_start;
-static t_pdp_conversion cached_conversion_array[CACHE_SIZE];
-
-/* mutex */
-static pthread_mutex_t pdp_hash_mutex;
-static pthread_mutex_t pdp_conversion_mutex;
-static pthread_mutex_t pdp_cache_mutex;
-
-#define HASHSIZE 1024
-static t_pdp_symbol *pdp_symhash[HASHSIZE];
-
-
-/* shamelessly copied from pd src and made thread safe */
-t_pdp_symbol *_pdp_dogensym(char *s, t_pdp_symbol *oldsym)
-{
- t_pdp_symbol **sym1, *sym2;
- unsigned int hash1 = 0, hash2 = 0;
- int length = 0;
- char *s2 = s;
- while (*s2)
- {
- hash1 += *s2;
- hash2 += hash1;
- length++;
- s2++;
- }
- sym1 = pdp_symhash + (hash2 & (HASHSIZE-1));
-
- /* lock hash */
- pthread_mutex_lock(&pdp_hash_mutex);
-
- while (sym2 = *sym1)
- {
- if (!strcmp(sym2->s_name, s)) goto gotit;
- sym1 = &sym2->s_next;
- }
- if (oldsym) sym2 = oldsym;
- else
- {
- sym2 = (t_pdp_symbol *)pdp_alloc(sizeof(*sym2));
- sym2->s_name = pdp_alloc(length+1);
- _pdp_symbol_clear_namespaces(sym2);
- sym2->s_next = 0;
- strcpy(sym2->s_name, s);
- }
- *sym1 = sym2;
-
- gotit:
-
- /* unlock hash */
- pthread_mutex_unlock(&pdp_hash_mutex);
- return (sym2);
-}
-
-t_pdp_symbol *pdp_gensym(char *s)
-{
- return(_pdp_dogensym(s, 0));
-}
-
-/* convert a type to a list */
-t_pdp_list *pdp_type_to_list(t_pdp_symbol *type)
-{
- char *c = type->s_name;
- char *lastname = c;
- char tmp[100];
- int n = 0;
- t_pdp_list *l = pdp_list_new(0);
-
- while(*c){
- if (*c == '/'){
- strncpy(tmp, lastname, n);
- tmp[n] = 0;
- pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(tmp));
- c++;
- lastname = c;
- n = 0;
- }
- else{
- c++;
- n++;
- }
- }
- pdp_list_add_back(l, a_symbol, (t_pdp_word)pdp_gensym(lastname));
-
- return l;
-}
-
-
-/* get the description symbol. this includes some compat transition stuff with a warning */
-t_pdp_symbol *pdp_packet_get_description(int packet)
-{
- t_pdp *header = pdp_packet_header(packet);
-
- if (!header) return pdp_gensym("invalid");
- else if (!header->desc){
- /* if description is not defined, try to reconstruct it (for backwards compat) */
- if (header->type == PDP_IMAGE){
- post("FIXME: pdp_type_get_description: packet %d has no description. using workaround.", packet);
- return pdp_packet_image_get_description(packet);
- }
- else
- return pdp_gensym("unknown");
- }
- else return header->desc;
-}
-
-
-
-/* this runs a conversion program */
-int _pdp_type_run_conversion_program(t_pdp_conversion_program *program,
- int packet, t_pdp_symbol *dest_template)
-{
- /* run a conversion program:
- treat the source packet as readonly, and cleanup intermediates, such
- that the net result is the production of a new packet, with the
- source packet intact. */
-
- int p, tmp;
-
- D post("DEBUG: _pdp_type_run_conversion_program: program = %x", program);
-
- // run the first line of the program
- D post("DEBUG: _pdp_type_run_conversion_program: method = %x", *program);
- p = (*program->method)(packet, dest_template);
- D post("DEBUG: _pdp_type_run_conversion_program: packet returned = %d, type = %s", p, pdp_packet_get_description(p)->s_name);
-
- // run the remaining lines + cleanup intermediates
- for (program = program->next; program ; program = program->next){
- D post("DEBUG: _pdp_type_run_conversion_program: next method ptr = %x", *program->method);
- tmp = (*program->method)(p, dest_template);
- pdp_packet_mark_unused(p);
- p = tmp;
- }
- return p;
-}
-
-
-/* find a conversion program */
-t_pdp_conversion_program *
-_pdp_type_find_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern)
-{
- t_pdp_conversion *c;
- t_pdp_conversion_program *retval = 0;
-
- /* lock conversion list */
- pthread_mutex_lock(&pdp_conversion_mutex);
-
- for (c = conversion_list; c; c=c->next){
- /* can be a wildcard match */
- if (pdp_type_description_match(src_pattern, c->src_pattern) &&
- pdp_type_description_match(dst_pattern, c->dst_pattern)) {
- /* found a program */
- D post("DEBUG: _pdp_type_find_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name);
- retval = c->program;
- goto gotit;
- }
- }
-
- /* no conversion program was found */
- retval = 0;
- gotit:
-
- /* lock conversion list */
- pthread_mutex_unlock(&pdp_conversion_mutex);
- return retval;
-}
-
-/* find a cached conversion program */
-t_pdp_conversion_program *
-_pdp_type_find_cached_conversion_program(t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern)
-{
- t_pdp_conversion *c;
- t_pdp_conversion_program *retval = 0;
-
- /* lock cached list */
- pthread_mutex_lock(&pdp_cache_mutex);
-
- for (c = cached_conversion_list_start; c; c=c->next){
- /* must be exact match */
- if ((src_pattern == c->src_pattern) &&
- (dst_pattern == c->dst_pattern)) {
- /* found a program */
- D post("DEBUG: _pdp_type_find_cached_conversion_program: found: %s -> %s", c->src_pattern->s_name, c->dst_pattern->s_name);
- retval = c->program;
- goto gotit;
- }
- }
-
- retval = 0;
-
- gotit:
-
- /* un lock cached list */
- pthread_mutex_unlock(&pdp_cache_mutex);
-
- /* no conversion program was found */
- return retval;
-}
-
-
-/* conversion program manipulations */
-void pdp_conversion_program_free(t_pdp_conversion_program *program)
-{
- t_pdp_conversion_program *p = 0;
- while (program) {
- p = program;
- program = program->next;
- pdp_dealloc (p);
- }
-}
-
-/* debug print */
-void _pdp_conversion_program_print(t_pdp_conversion_program *program)
-{
- D post("DEBUG: conversion program: %x", program);
- while(program){
- D post("DEBUG: method: %x", program->method);
- program = program->next;
- }
-}
-
-t_pdp_conversion_program *pdp_conversion_program_new(t_pdp_conversion_method method, ...)
-{
- t_pdp_conversion_program head;
- t_pdp_conversion_program *p = &head;
- t_pdp_conversion_method m = method;
- va_list ap;
-
- D post("DEBUG: pdp_conversion_program_new:BEGIN");
-
- p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p));
- p->method = m;
- va_start(ap, method);
- while (m = va_arg(ap, t_pdp_conversion_method)){
- p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p));
- p->method = m;
- }
- p->next = 0; // terminate list
- va_end(ap);
-
- D post("DEBUG: pdp_conversion_program_new:END");
- D _pdp_conversion_program_print(head.next);
-
- return head.next;
-}
-
-t_pdp_conversion_program *pdp_conversion_program_copy(t_pdp_conversion_program *program)
-{
- t_pdp_conversion_program head;
- t_pdp_conversion_program *p = &head;
-
- for(;program; program=program->next){
- p = p->next = (t_pdp_conversion_program *)pdp_alloc(sizeof(*p));
- p->method = program->method;
- }
- p->next = 0;
- return head.next;
-}
-
-void pdp_conversion_program_add(t_pdp_conversion_program *program, t_pdp_conversion_program *tail)
-{
- t_pdp_conversion_program *p = program;
-
- //D post("DEBUG: pdp_conversion_program_add:BEGIN");
-
-
- while (p->next) p = p->next;
- p->next = pdp_conversion_program_copy(tail);
-
- //D post("DEBUG: pdp_conversion_program_add:END");
-
-}
-
-/* conversion registration */
-void pdp_type_register_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program)
-{
- t_pdp_conversion head;
- t_pdp_conversion *c = &head;
-
- /* lock conversion list */
- pthread_mutex_lock(&pdp_conversion_mutex);
-
- head.next = conversion_list;
-
- while (c->next) c=c->next; // add a new one to the end
- c = c->next = (t_pdp_conversion *)pdp_alloc(sizeof(*c));
- c->src_pattern = src_pattern;
- c->dst_pattern = dst_pattern;
- c->program = program;
- c->next = 0;
-
- conversion_list = head.next;
-
- /* unlock conversion list */
- pthread_mutex_unlock(&pdp_conversion_mutex);
-
-}
-
-/* register a cached conversion */
-void pdp_type_register_cached_conversion (t_pdp_symbol *src_pattern, t_pdp_symbol *dst_pattern, t_pdp_conversion_program *program)
-{
-
- t_pdp_conversion *save, *c, *c2;
-
- /* unlock cahed conversion list */
- pthread_mutex_lock(&pdp_cache_mutex);
-
- c2 = save = cached_conversion_list_start;
- while (c2->next->next) c2 = c2->next;
- c = c2->next;
- c2->next = 0;
- if (c->program) pdp_conversion_program_free(c->program);
- c->src_pattern = src_pattern;
- c->dst_pattern = dst_pattern;
- c->program = program;
- c->next = save;
- cached_conversion_list_start = c;
-
- /* unlock cached conversion list */
- pthread_mutex_unlock(&pdp_cache_mutex);
-}
-
-/* convert a given packet to a certain type (template) */
-int _pdp_packet_convert(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
- t_pdp_symbol *tmp_type = 0;
- int tmp_packet = -1;
-
- t_pdp_conversion_program *program = 0;
- t_pdp_conversion_program *program_last = 0;
- t_pdp_conversion_program *program_tail = 0;
-
- /* check if there is a program in the cached list, if so run it */
- if (program = _pdp_type_find_cached_conversion_program(type, dest_template))
- return _pdp_type_run_conversion_program(program, packet, dest_template);
-
- /* if it is not cached, iteratively convert
- and save program on top of cache list if a conversion path (program) was found */
-
- // run first conversion that matches
- program = pdp_conversion_program_copy(_pdp_type_find_conversion_program(type, dest_template));
- program_last = program;
- if (!program){
- D post("DEBUG: pdp_type_convert: (1) can't convert %s to %s", type->s_name, dest_template->s_name);
- return -1;
- }
- tmp_packet = _pdp_type_run_conversion_program(program, packet, dest_template);
- tmp_type = pdp_packet_get_description(tmp_packet);
-
- // run more conversions if necessary, deleting intermediate packets
- while (!pdp_type_description_match(tmp_type, dest_template)){
- int new_packet;
- program_tail = _pdp_type_find_conversion_program(tmp_type, dest_template);
- if (!program_tail){
- D post("DEBUG: pdp_type_convert: (2) can't convert %s to %s", tmp_type->s_name, dest_template->s_name);
- pdp_packet_mark_unused(tmp_packet);
- pdp_conversion_program_free(program);
- return -1;
- }
- if (program_last == program_tail){
- post("ERROR: pdp_packet_convert: conversion loop detected");
- }
- program_last = program_tail;
-
- pdp_conversion_program_add(program, program_tail);
- new_packet = _pdp_type_run_conversion_program(program_tail, tmp_packet, dest_template);
- pdp_packet_mark_unused(tmp_packet);
- tmp_packet = new_packet;
- tmp_type = pdp_packet_get_description(tmp_packet);
- }
-
- // save the conversion program
- pdp_type_register_cached_conversion(type, dest_template, program);
-
- // return resulting packet
- return tmp_packet;
-
-}
-
-/* convert or copy ro */
-int pdp_packet_convert_ro(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
-
- /* if it is compatible, return a ro copy */
- if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_ro(packet);
-
- /* if not, convert to a new type */
- else return _pdp_packet_convert(packet, dest_template);
-}
-
-/* convert or copy rw */
-int pdp_packet_convert_rw(int packet, t_pdp_symbol *dest_template)
-{
- t_pdp_symbol *type = pdp_packet_get_description(packet);
-
- /* if it is compatible, just return a rw copy */
- if (pdp_type_description_match(type, dest_template)) return pdp_packet_copy_rw(packet);
-
- /* if not, convert to a new type */
- else return _pdp_packet_convert(packet, dest_template);
-}
-
-
-static void _setup_type_cache(t_pdp_symbol *s)
-{
- t_pdp_list *l = pdp_type_to_list(s);
- pthread_mutex_lock(&pdp_hash_mutex); //lock to prevent re-entry
- if (!s->s_type){
- s->s_type = l;
- l = 0;
- }
- pthread_mutex_unlock(&pdp_hash_mutex);
- if (l) pdp_list_free(l);
-}
-
-/* check if a type description fits a template
- this function is symmetric */
-int pdp_type_description_match(t_pdp_symbol *description, t_pdp_symbol *pattern)
-{
-
-
-#if 1
- t_pdp_atom *ad, *ap;
- t_pdp_symbol *wildcard = pdp_gensym("*");
-
- /* same type -> match */
- if (description == pattern) return 1;
-
- /* use the description list stored in the symbol for comparison */
- if (!(description->s_type)) _setup_type_cache(description);
- if (!(pattern->s_type)) _setup_type_cache(pattern);
-
- /* check size */
- if (description->s_type->elements != pattern->s_type->elements) return 0;
-
- /* compare symbols of type list */
- for(ad=description->s_type->first, ap=pattern->s_type->first; ad; ad=ad->next, ap=ap->next){
- if (ad->w.w_symbol == wildcard) continue;
- if (ap->w.w_symbol == wildcard) continue;
- if (ad->w.w_symbol != ap->w.w_symbol) return 0; /* difference and not a wildcard */
- }
-
- /* type templates match */
- return 1;
-
-
-#else
- int retval = 0;
- if (description == pattern) retval = 1;
- //else retval = (!fnmatch(pattern->s_name, description->s_name, FNM_FILE_NAME));
-
- //hack: make a symmetric match symmetric by calling fnmatch a second time with reversed attributes
- else retval = ((!fnmatch(pattern->s_name, description->s_name, FNM_FILE_NAME))
- ||(!fnmatch(description->s_name, pattern->s_name, FNM_FILE_NAME)));
-
-
- D post("DEBUG: testing match between %s and %s: %s", description->s_name, pattern->s_name, retval ? "match" : "no match");
-
- return retval;
-#endif
-}
-
-
-
-
-
-/* setup method */
-void pdp_type_setup(void)
-{
- int i;
-
- // create mutexes
- pthread_mutex_init(&pdp_hash_mutex, NULL);
- pthread_mutex_init(&pdp_conversion_mutex, NULL);
- pthread_mutex_init(&pdp_cache_mutex, NULL);
-
- // init hash
- memset(pdp_symhash, 0, HASHSIZE * sizeof(t_pdp_symbol *));
-
- // init conversion lists
- conversion_list = 0;
- for(i=0; i<CACHE_SIZE; i++){
- t_pdp_conversion *c = cached_conversion_array + i;
- c->src_pattern = 0;
- c->dst_pattern = 0;
- c->program = 0;
- c->next = c + 1;
- }
- cached_conversion_list_start = cached_conversion_array;
- cached_conversion_array[CACHE_SIZE-1].next = 0;
-
-
-
-}
diff --git a/system/kernel/pdp_ut.c b/system/kernel/pdp_ut.c
deleted file mode 100644
index dadc493..0000000
--- a/system/kernel/pdp_ut.c
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Pure Data Packet - Utility toolkit objects.
- * Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-/* This file contains some small utility pd objects that make working with
- pdp objects a lot easier. Mainly as glue to be used in the abstractions
- in the distro. */
-
-
-#include "pdp.h"
-#include <math.h>
-
-/* this object does an add, scale, clip operation */
-
-t_class *pdp_ut_addscaleclip_class;
-
-typedef struct pdp_ut_addscaleclip_struct
-{
- t_object x_obj;
- t_outlet *x_outlet0;
- t_float x_min;
- t_float x_max;
- t_float x_offset;
- t_float x_scale;
-} t_pdp_ut_addscaleclip;
-
-
-static void pdp_ut_addscaleclip_float(t_pdp_ut_addscaleclip *x, t_floatarg f)
-{
- f += x->x_offset;
- f *= x->x_scale;
- f = (f < x->x_min) ? x->x_min : f;
- f = (f > x->x_max) ? x->x_max : f;
- outlet_float(x->x_outlet0, f);
-}
-
-static void pdp_ut_addscaleclip_free(t_pdp_ut_addscaleclip *x){}
-
-void *pdp_ut_addscaleclip_new(t_floatarg offset, t_floatarg scale, t_floatarg min, t_floatarg max)
-{
- t_pdp_ut_addscaleclip *x = (t_pdp_ut_addscaleclip *)pd_new(pdp_ut_addscaleclip_class);
- x->x_outlet0 = outlet_new(&x->x_obj, &s_float);
- x->x_offset = offset;
- x->x_scale = scale;
- x->x_min = min;
- x->x_max = max;
- return (void *)x;
-}
-
-void pdp_ut_addscaleclip_setup(void)
-{
- pdp_ut_addscaleclip_class = class_new(gensym("pdp_ut_addscaleclip"), (t_newmethod)pdp_ut_addscaleclip_new,
- (t_method)pdp_ut_addscaleclip_free, sizeof(t_pdp_ut_addscaleclip), 0,
- A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
- class_addfloat(pdp_ut_addscaleclip_class, pdp_ut_addscaleclip_float);
-}
-
-
-/* pdp_ut_logmap does a logarithmic parameter mapping [0->1] x -> min(max/min)^x max an add, scale, clip operation */
-/* pdp_ut_logmap_comp does x -> min(max/min)^(1-x) */
-/* pdp_ut_linmap dos x -> min + (max - min * x */
-
-t_class *pdp_ut_linmap_class;
-t_class *pdp_ut_logmap_class;
-t_class *pdp_ut_logmap_comp_class;
-
-typedef struct pdp_ut_map_struct
-{
- t_object x_obj;
- t_outlet *x_outlet0;
- t_float x_min;
- t_float x_max;
-} t_pdp_ut_map;
-
-
-static void pdp_ut_logmap_float(t_pdp_ut_map *x, t_floatarg f)
-{
- f = (f < 0.0f) ? 0.0f : f;
- f = (f > 1.0f) ? 1.0f : f;
-
- f = x->x_min * pow((x->x_max / x->x_min), f);
-
- outlet_float(x->x_outlet0, f);
-}
-
-static void pdp_ut_linmap_float(t_pdp_ut_map *x, t_floatarg f)
-{
- f = (f < 0.0f) ? 0.0f : f;
- f = (f > 1.0f) ? 1.0f : f;
-
- f = x->x_min + ((x->x_max - x->x_min) * f);
-
- outlet_float(x->x_outlet0, f);
-}
-
-static void pdp_ut_logmap_comp_float(t_pdp_ut_map *x, t_floatarg f)
-{
- f = (f < 0.0f) ? 0.0f : f;
- f = (f > 1.0f) ? 1.0f : f;
-
- f = x->x_min * pow((x->x_max / x->x_min), (1.0f - f));
-
- outlet_float(x->x_outlet0, f);
-}
-
-static void pdp_ut_map_free(t_pdp_ut_map *x){}
-
-
-void pdp_ut_map_init(t_pdp_ut_map *x, t_floatarg min, t_floatarg max)
-{
- x->x_outlet0 = outlet_new(&x->x_obj, &s_float);
- x->x_min = min;
- x->x_max = max;
-}
-
-void *pdp_ut_logmap_new(t_floatarg min, t_floatarg max)
-{
- t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_class);
- pdp_ut_map_init(x, min, max);
- return (void *)x;
-}
-
-void *pdp_ut_linmap_new(t_floatarg min, t_floatarg max)
-{
- t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_linmap_class);
- pdp_ut_map_init(x, min, max);
- return (void *)x;
-}
-
-void *pdp_ut_logmap_comp_new(t_floatarg min, t_floatarg max)
-{
- t_pdp_ut_map *x = (t_pdp_ut_map *)pd_new(pdp_ut_logmap_comp_class);
- pdp_ut_map_init(x, min, max);
- return (void *)x;
-}
-
-void pdp_ut_logmap_setup(void)
-{
- pdp_ut_logmap_class = class_new(gensym("pdp_ut_logmap"), (t_newmethod)pdp_ut_logmap_new,
- (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0,
- A_FLOAT, A_FLOAT, A_NULL);
- class_addfloat(pdp_ut_logmap_class, pdp_ut_logmap_float);
-}
-
-void pdp_ut_logmap_comp_setup(void)
-{
- pdp_ut_logmap_comp_class = class_new(gensym("pdp_ut_logmap_comp"), (t_newmethod)pdp_ut_logmap_comp_new,
- (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0,
- A_FLOAT, A_FLOAT, A_NULL);
- class_addfloat(pdp_ut_logmap_comp_class, pdp_ut_logmap_comp_float);
-}
-
-void pdp_ut_linmap_setup(void)
-{
- pdp_ut_linmap_class = class_new(gensym("pdp_ut_linmap"), (t_newmethod)pdp_ut_linmap_new,
- (t_method)pdp_ut_map_free, sizeof(t_pdp_ut_map), 0,
- A_FLOAT, A_FLOAT, A_NULL);
- class_addfloat(pdp_ut_linmap_class, pdp_ut_linmap_float);
-}
-
-
-
-t_class *pdp_ut_rgb2ycrcb_class;
-
-typedef struct pdp_ut_rgb2ycrcb
-{
- t_object x_obj;
- t_outlet *x_outlet_luma;
- t_outlet *x_outlet_chroma_red;
- t_outlet *x_outlet_chroma_blue;
-
- t_float x_red, x_green, x_blue;
-
-} t_pdp_ut_rgb2ycrcb;
-
-
-static void pdp_ut_rgb2ycrcb_bang (t_pdp_ut_rgb2ycrcb* x)
-{
-
- float luma = 0.299f * x->x_red + 0.587f * x->x_green + 0.114f * x->x_blue;
- float chroma_red = (x->x_red - luma) * 0.713f;
- float chroma_blue = (x->x_blue - luma) * 0.565f;
-
- outlet_float(x->x_outlet_chroma_blue, chroma_blue);
- outlet_float(x->x_outlet_chroma_red, chroma_red);
- outlet_float(x->x_outlet_luma, luma);
-
-}
-
-
-static void pdp_ut_rgb2ycrcb_red (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_red = f; pdp_ut_rgb2ycrcb_bang(x);}
-static void pdp_ut_rgb2ycrcb_green (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_green = f; pdp_ut_rgb2ycrcb_bang(x);}
-static void pdp_ut_rgb2ycrcb_blue (t_pdp_ut_rgb2ycrcb* x, t_floatarg f) {x->x_blue = f; pdp_ut_rgb2ycrcb_bang(x);}
-
-
-
-static void pdp_ut_rgb2ycrcb_free (t_pdp_ut_rgb2ycrcb* x) {}
-static void* pdp_ut_rgb2ycrcb_new(void)
-{
- t_pdp_ut_rgb2ycrcb *x = (t_pdp_ut_rgb2ycrcb *)pd_new(pdp_ut_rgb2ycrcb_class);
-
-
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("green"));
- inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("blue"));
-
- x->x_outlet_luma = outlet_new(&x->x_obj, &s_float);
- x->x_outlet_chroma_red = outlet_new(&x->x_obj, &s_float);
- x->x_outlet_chroma_blue = outlet_new(&x->x_obj, &s_float);
-
- x->x_red = 0.0f;
- x->x_green = 0.0f;
- x->x_blue = 0.0f;
-
-
- return (void *)x;
-}
-
-void pdp_ut_rgb2ycrcb_setup(void)
-{
- pdp_ut_rgb2ycrcb_class = class_new(gensym("pdp_ut_rgb2ycrcb"), (t_newmethod)pdp_ut_rgb2ycrcb_new,
- (t_method)pdp_ut_rgb2ycrcb_free, sizeof(t_pdp_ut_rgb2ycrcb), 0, A_NULL);
- class_addfloat(pdp_ut_rgb2ycrcb_class, pdp_ut_rgb2ycrcb_red);
- class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_green, gensym("green"), A_FLOAT, A_NULL);
- class_addmethod(pdp_ut_rgb2ycrcb_class, (t_method)pdp_ut_rgb2ycrcb_blue, gensym("blue"), A_FLOAT, A_NULL);
-}
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-void pdp_ut_setup(void)
-{
- pdp_ut_addscaleclip_setup();
- pdp_ut_logmap_setup();
- pdp_ut_logmap_comp_setup();
- pdp_ut_linmap_setup();
- pdp_ut_rgb2ycrcb_setup();
-}
-
-
-#ifdef __cplusplus
-}
-#endif