+/*
+ * CINELERRA
+ * Copyright (C) 2020 William Morrow
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
trace_locks = 0;
while( lock_table.last ) {
lock_item *p = (lock_item*)lock_table.last;
+ lock_table.remove_pointer(p);
p->info->trace = 0;
- lock_table.remove_pointer(p); lock_free.append(p);
+ lock_free.append(p);
}
lock_free.clear();
lock_table.unlock();
p = (lock_item*)lock_table.last;
while( p && p->id != table_id ) p = (lock_item*)p->previous;
}
- else
- info->trace = 0;
- if( p ) { lock_table.remove_pointer(p); lock_free.append(p); }
+ if( p ) {
+ if( p->list == &lock_table ) {
+ lock_table.remove_pointer(p);
+ info->trace = 0;
+ lock_free.append(p);
+ }
+ else
+ printf("unset_lock2: free lock_item in lock_table %p\n", p);
+ }
lock_table.unlock();
}
p = (lock_item*)lock_table.last;
while( p && ( p->info!=info || !p->is_owner ) ) p = (lock_item*)p->previous;
}
- else
- info->trace = 0;
- if( p ) { lock_table.remove_pointer(p); lock_free.append(p); }
+ info->trace = 0;
+ if( p ) {
+ if( p->list == &lock_table ) {
+ lock_table.remove_pointer(p);
+ info->trace = 0;
+ lock_free.append(p);
+ }
+ else
+ printf("unset_lock: free lock_item in lock_table %p\n", p);
+ }
lock_table.unlock();
}
{
if( !global_trace || !trace_locks ) return;
lock_table.lock();
+ info->trace = 0;
lock_item *p = (lock_item*)lock_table.first;
while( p ) {
lock_item *lp = p; p = (lock_item*)p->next;
if( lp->info != info ) continue;
- lock_table.remove_pointer(lp); lock_free.append(lp);
+ lock_table.remove_pointer(lp);
+ lock_free.append(lp);
}
lock_table.unlock();
}
while( p ) {
lock_item *lp = p; p = (lock_item*)p->next;
if( lp->tid != tid ) continue;
- lock_table.remove_pointer(lp); lock_free.append(lp);
+ lock_table.remove_pointer(lp);
+ lp->info->trace = 0;
+ lock_free.append(lp);
}
lock_table.unlock();
}
}
}
+void trace_info::set_owner() { owner = (unsigned long)pthread_self(); }
+void trace_info::unset_owner() { owner = 0; }
+
void BC_Trace::dump_locks(FILE *fp)
{
// Dump lock table
fprintf(fp,"signal_entry: lock table size=%d\n", lock_table.size);
for( trace_item *tp=lock_table.first; tp!=0; tp=tp->next ) {
lock_item *p=(lock_item*)tp;
- fprintf(fp," %p %s %s %p%s\n", p->info, p->title,
- p->loc, (void*)p->tid, p->is_owner ? " *" : "");
+ fprintf(fp," %p %s, %s %p%s",
+ p->info, p->title, p->loc,
+ (void*)p->tid, p->is_owner ? " *" : "");
+ if( p->info->owner && p->info->owner != (unsigned long)p->tid )
+ fprintf(fp," %p", (void*)p->info->owner);
+ fprintf(fp,"\n");
}
+ int64_t lock_total = lock_table.total();
+ int64_t free_total = lock_free.total();
+ printf("lock_items: %jd\n", lock_total);
+ printf("lock_frees: %jd\n", free_total);
+ int64_t missed_locks = lock_table.size - (lock_total + free_total);
+ if( missed_locks )
+ printf("miss locks: %jd\n", missed_locks);
#endif
}