From 8201450efc105691e343c50b4eab946f7b0ee038 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Tue, 11 Jan 2011 16:46:38 +0100 Subject: Now keeping track of unused shared objects and maybe unloading them --- TODO | 9 +++--- TODO.done | 1 + synth/.depend | 21 ++++++++----- synth/Makefile | 2 +- synth/note_loader.cpp | 10 +++---- synth/programs.cpp | 10 +++++++ synth/shared_object_manager.cpp | 65 +++++++++++++++++++++++++++++++++++++++++ synth/shared_object_manager.h | 8 +++++ 8 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 synth/shared_object_manager.cpp create mode 100644 synth/shared_object_manager.h diff --git a/TODO b/TODO index 03a1783..4b10c50 100644 --- a/TODO +++ b/TODO @@ -3,10 +3,8 @@ TODO für den synth o bei envelopes: releasephase abschalten (bei sustain bleiben) - - o programme on-the-fly (um)laden - beim entladen des alten programms: ggf. shared objekt löschen - + + o on-the-fly die LFOs ändern (frequenz, wellenform) o RAM aufräumen? o beide parser: envelopes von oscs mit out=0 standardmäßig deaktivieren @@ -14,6 +12,8 @@ TODO für den synth lassen? d.h. via init funktionspointer übergeben oder virtuelle interfaceklassen benutzen (für envelope/filter z.B.) + (o)bei program change vielleicht nicht _ALLE_ controller resetten? + o KSL mit powf und floats statt mit double umschreiben o statt lfo-nummer direkten zugriff auf curr_lfo angeben? o bei tremolo (und vibrato?): eventuell nicht prüfen, obs aktiviert @@ -36,6 +36,7 @@ TODO für den synth o konnte-nicht-verbinden-warnung weniger schlimm machen o max_pitchbend per controller setzen? + per RPN, NRPN o nur auf bestimmte channels reagieren (o)bei filter-envelopes: ksr/ksl? nää. diff --git a/TODO.done b/TODO.done index 654ff17..f0e9552 100644 --- a/TODO.done +++ b/TODO.done @@ -60,6 +60,7 @@ TODO für den synth x notes compilieren und als .so-datei laden x parser-klasse durch parse-funktion ersetzen x sostenuto-, halte-, legato-, soft-pedal + x programme on-the-fly (um)laden TODO fürs CLI diff --git a/synth/.depend b/synth/.depend index fb0d8aa..ba430bb 100644 --- a/synth/.depend +++ b/synth/.depend @@ -9,12 +9,12 @@ filter.o: filter.cpp filter.h fixed.h defines.h globals.h programs.h \ globals.o: globals.cpp globals.h programs.h fixed.h note_funcs.h \ channel.h note_skel.h defines.h util.h jack.o: jack.cpp defines.h globals.h programs.h fixed.h note_funcs.h \ - channel.h note_skel.h util.h jack.h + channel.h note_skel.h util.h jack.h communication.h load.o: load.cpp util.h programs.h fixed.h note_funcs.h globals.h \ - channel.h note_skel.h defines.h -main.o: main.cpp jack.h load.h cli.h parser.h fixed.h programs.h \ - note_funcs.h channel.h note_skel.h defines.h util.h globals.h \ - note_loader.h + channel.h note_skel.h defines.h parser.h note_loader.h +main.o: main.cpp jack.h load.h programs.h fixed.h note_funcs.h cli.h \ + channel.h note_skel.h defines.h util.h globals.h in_synth_cli.h \ + communication.h note_loader.h note.o: note.cpp note.h programs.h fixed.h note_funcs.h envelope.h \ filter.h note_skel.h globals.h channel.h defines.h util.h note_skel.o: note_skel.cpp note_skel.h programs.h fixed.h note_funcs.h \ @@ -22,10 +22,17 @@ note_skel.o: note_skel.cpp note_skel.h programs.h fixed.h note_funcs.h \ parser.o: parser.cpp parser.h fixed.h programs.h note_funcs.h defines.h \ globals.h channel.h note_skel.h util.h readwave.h programs.o: programs.cpp programs.h fixed.h note_funcs.h globals.h \ - channel.h note_skel.h defines.h util.h + channel.h note_skel.h defines.h util.h shared_object_manager.h readwave.o: readwave.cpp readwave.h programs.h fixed.h note_funcs.h \ util.h util.o: util.cpp util.h programs.h fixed.h note_funcs.h globals.h \ channel.h note_skel.h defines.h note_loader.o: note_loader.cpp note_loader.h programs.h fixed.h \ - note_funcs.h globals.h channel.h note_skel.h defines.h util.h + note_funcs.h globals.h channel.h note_skel.h defines.h util.h \ + shared_object_manager.h +in_synth_cli.o: in_synth_cli.cpp in_synth_cli.h util.h programs.h fixed.h \ + note_funcs.h communication.h globals.h channel.h note_skel.h defines.h \ + load.h +communication.o: communication.cpp communication.h +shared_object_manager.o: shared_object_manager.cpp util.h programs.h \ + fixed.h note_funcs.h shared_object_manager.h diff --git a/synth/Makefile b/synth/Makefile index 2f16297..8109bc8 100644 --- a/synth/Makefile +++ b/synth/Makefile @@ -3,7 +3,7 @@ CFLAGS=-Wall -g CXXFLAGS=$(CFLAGS) LDFLAGS=-lm `pkg-config --cflags --libs jack` -OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o in_synth_cli.o communication.o +OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o in_synth_cli.o communication.o shared_object_manager.o BIN=synth DEPENDFILE = .depend diff --git a/synth/note_loader.cpp b/synth/note_loader.cpp index 28613b9..d322552 100644 --- a/synth/note_loader.cpp +++ b/synth/note_loader.cpp @@ -6,6 +6,7 @@ #include "programs.h" #include "note_funcs.h" #include "globals.h" +#include "shared_object_manager.h" using namespace std; @@ -13,10 +14,7 @@ void load_note_from_so(string file, program_t &prog) { void *handle; - handle = dlopen(file.c_str(), RTLD_LAZY); - - if (handle==NULL) - throw string("could not open shared object (")+string(dlerror())+string(")"); + handle = my_dlopen(file); try { @@ -38,7 +36,7 @@ void load_note_from_so(string file, program_t &prog) { prog.create_func=NULL; prog.dl_handle=NULL; - dlclose(handle); + dlref_dec(handle); throw err; } } @@ -47,7 +45,7 @@ void maybe_unload_note(program_t &prog) { if (prog.dl_handle) { - dlclose(prog.dl_handle); + dlref_dec(prog.dl_handle); prog.dl_handle=NULL; prog.create_func=NULL; } diff --git a/synth/programs.cpp b/synth/programs.cpp index 094f209..b896a06 100644 --- a/synth/programs.cpp +++ b/synth/programs.cpp @@ -1,8 +1,10 @@ #include #include +#include #include "programs.h" #include "globals.h" +#include "shared_object_manager.h" using namespace std; @@ -78,6 +80,12 @@ void program_t::cleanup() delete [] pfactor.fm[i]; delete [] pfactor.fm; } + + if (dl_handle) + dlref_dec(dl_handle); + + dl_handle=NULL; + create_func=NULL; } program_t& program_t::operator=(const program_t &that) @@ -121,6 +129,8 @@ program_t& program_t::operator=(const program_t &that) this->create_func=that.create_func; this->dl_handle=that.dl_handle; + if (dl_handle) + dlref_inc(dl_handle); return *this; } diff --git a/synth/shared_object_manager.cpp b/synth/shared_object_manager.cpp new file mode 100644 index 0000000..045f409 --- /dev/null +++ b/synth/shared_object_manager.cpp @@ -0,0 +1,65 @@ +#include +#include +#include + +#include "util.h" +#include "shared_object_manager.h" + +using namespace std; + +map dl_ref_count; + +void* my_dlopen(string file) +{ + void* handle; + + if (file.find('/')==string::npos) + file="./"+file; + + handle=dlopen(file.c_str(),RTLD_NOW); + + if (handle==NULL) + throw string("could not open shared object (")+string(dlerror())+string(")"); + + if (dl_ref_count[handle]!=0) //the library is already opened + { + output_verbose("the requested shared object '"+file+"' is already opened, reusing the handle #"+IntToStr(int(handle))); + dlclose(handle); //we don't need it opened twice + } + else + { + output_verbose("the requested shared object '"+file+"' has been loaded with handle #"+IntToStr(int(handle))); + } + + dl_ref_count[handle]++; + + return handle; +} + +void dlref_inc(void* handle) +{ + if (handle==NULL) + throw string("dlref_inc: tried to increment the ref-count for NULL"); + + if (dl_ref_count[handle]==0) + throw string("dlref_inc: tried to increment the ref-count for a nonexistent handle"); + + dl_ref_count[handle]++; +} + +void dlref_dec(void* handle) +{ + if (handle==NULL) + throw string("dlref_inc: tried to increment the ref-count for NULL"); + + if (dl_ref_count[handle]==0) + throw string("dlref_inc: tried to decrement the ref-count for a nonexistent handle"); + + dl_ref_count[handle]--; + + if (dl_ref_count[handle]==0) + { + output_verbose("noone uses dl-handle "+IntToStr(int(handle))+", unloading the shared object..."); + dlclose(handle); + } +} diff --git a/synth/shared_object_manager.h b/synth/shared_object_manager.h new file mode 100644 index 0000000..5927408 --- /dev/null +++ b/synth/shared_object_manager.h @@ -0,0 +1,8 @@ +#ifndef __SHARED_OBJECT_MANAGER__ +#define __SHARED_OBJECT_MANAGER__ + +void* my_dlopen(string file); +void dlref_inc(void* handle); +void dlref_dec(void* handle); + +#endif -- cgit v1.2.1