Browse Source

Revert "try to make data structures thread save by using a mutex"

This reverts commit 88d64d65ab.
1.0.0
Georg Hopp 11 years ago
parent
commit
21cf5258cb
  1. 6
      include/tr/hash.h
  2. 3
      include/tr/queue.h
  3. 23
      include/tr/tree.h
  4. 2
      src/Makefile.am
  5. 2
      src/hash/add.c
  6. 6
      src/hash/cleanup.c
  7. 4
      src/hash/delete.c
  8. 2
      src/hash/each.c
  9. 4
      src/hash/get.c
  10. 2
      src/hash/get_first.c
  11. 6
      src/hash/hash.c
  12. 13
      src/queue/delete.c
  13. 5
      src/queue/destroy.c
  14. 7
      src/queue/get.c
  15. 6
      src/queue/put.c
  16. 6
      src/queue/put_first.c
  17. 7
      src/queue/queue.c
  18. 1
      src/tree/Makefile.am
  19. 29
      src/tree/delete.c
  20. 12
      src/tree/destroy.c
  21. 11
      src/tree/find.c
  22. 22
      src/tree/insert.c
  23. 9
      src/tree/tree.c
  24. 50
      src/tree/tree_node.c
  25. 6
      src/tree/walk.c

6
include/tr/hash.h

@ -28,16 +28,16 @@
#include "trbase.h"
#include "tr/tree.h"
#define TR_HASH_IS_EMPTY(h) ((h)->tree->root)
#define TR_HASH_IS_EMPTY(h) ((h)->root)
TR_CLASS(TR_Hash) {
TR_Tree tree;
TR_Tree root;
int cleanup_no_free;
};
TR_INSTANCE_INIT(TR_Hash);
TR_CLASSVARS_DECL(TR_Hash) {};
#define TR_hashEmpty(hash) (NULL == (hash)->tree->root)
#define TR_hashEmpty(hash) (NULL == (hash)->root)
void * TR_hashAdd(TR_Hash, void *);
void * TR_hashDelete(TR_Hash, const char *, size_t);

3
include/tr/queue.h

@ -26,7 +26,6 @@
#ifndef __TR_QUEUE_H__
#define __TR_QUEUE_H__
#include <pthread.h>
#include <sys/types.h>
#include "trbase.h"
@ -36,8 +35,6 @@ TR_CLASS(TR_Queue) {
void * msg;
TR_Queue next;
pthread_mutex_t lock;
/**
* first and last are only available in the initial queue
* element (the root). This elelment does not contain any message

23
include/tr/tree.h

@ -23,26 +23,17 @@
#ifndef __TR_TREE_H__
#define __TR_TREE_H__
#include <pthread.h>
#include "tr/tree_macros.h"
#include "trbase.h"
TR_CLASS(TR_TreeNode) {
TR_CLASS(TR_Tree) {
void * data;
TR_rbColor color;
TR_TreeNode parent;
TR_TreeNode left;
TR_TreeNode right;
};
TR_INSTANCE_INIT(TR_TreeNode);
TR_CLASSVARS_DECL(TR_TreeNode) {};
TR_CLASS(TR_Tree) {
TR_TreeNode root;
pthread_mutex_t lock;
TR_Tree parent;
TR_Tree left;
TR_Tree right;
};
TR_INSTANCE_INIT(TR_Tree);
TR_CLASSVARS_DECL(TR_Tree) {};
@ -51,10 +42,10 @@ typedef int (*TR_TreeComp)(const void *, const void *);
typedef void (*TR_TreeAction)(const void *, const void *, const int);
void * TR_treeFind(TR_Tree, const void *, TR_TreeComp);
void * TR_treeInsert(TR_Tree, const void *, TR_TreeComp);
void * TR_treeDelete(TR_Tree, const void *, TR_TreeComp);
void * TR_treeInsert(TR_Tree *, const void *, TR_TreeComp);
void * TR_treeDelete(TR_Tree *, const void *, TR_TreeComp);
void TR_treeWalk(TR_Tree, const void *, TR_TreeAction);
void TR_treeDestroy(TR_Tree, TR_TreeAction);
void TR_treeDestroy(TR_Tree *, TR_TreeAction);
#endif // __TR_TREE_H__

2
src/Makefile.am

@ -11,7 +11,7 @@ TRDATALIBS = cbuf/libcbuf.la \
lib_LTLIBRARIES = libtrdata.la
libtrdata_la_SOURCES =
libtrdata_la_CFLAGS = $(AM_CFLAGS) -lpthread
libtrdata_la_CFLAGS = $(AM_CFLAGS)
libtrdata_la_LIBADD = $(TRDATALIBS)
SUBDIRS = cbuf hash queue tree

2
src/hash/add.c

@ -48,7 +48,7 @@ hashAddComp(const void * a, const void * b)
void *
TR_hashAdd(TR_Hash this, void * operand)
{
void * found = TR_treeInsert(this->tree, operand, hashAddComp);
void * found = TR_treeInsert(&this->root, operand, hashAddComp);
if (NULL == found) {
return NULL;

6
src/hash/cleanup.c

@ -36,12 +36,10 @@ void
TR_hashCleanup(TR_Hash this)
{
if (this->cleanup_no_free) {
TR_treeDestroy(this->tree, NULL);
TR_treeDestroy(&(this->root), NULL);
} else {
TR_treeDestroy(this->tree, tDelete);
TR_treeDestroy(&(this->root), tDelete);
}
TR_delete(this->tree);
}
// vim: set ts=4 sw=4:

4
src/hash/delete.c

@ -51,7 +51,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
void * found = NULL;
found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
found = TR_treeDelete(&(this->root), &hash, hashDeleteComp);
return found;
}
@ -59,7 +59,7 @@ TR_hashDelete(TR_Hash this, const char * search, size_t nsearch)
void *
TR_hashDeleteByVal(TR_Hash this, unsigned long hash)
{
void * found = TR_treeDelete(this->tree, &hash, hashDeleteComp);
void * found = TR_treeDelete(&(this->root), &hash, hashDeleteComp);
return found;
}

2
src/hash/each.c

@ -42,7 +42,7 @@ TR_hashEach(
{
cb = callback;
TR_treeWalk(this->tree, data, walk);
TR_treeWalk(this->root, data, walk);
}
// vim: set ts=4 sw=4:

4
src/hash/get.c

@ -52,7 +52,7 @@ void *
TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
{
unsigned long hash = TR_sdbm((const unsigned char *)search, nsearch);
void * found = TR_treeFind(this->tree, &hash, hashGetComp);
void * found = TR_treeFind(this->root, &hash, hashGetComp);
return found;
}
@ -60,7 +60,7 @@ TR_hashGet(TR_Hash this, const char * search, size_t nsearch)
void *
TR_hashGetByVal(TR_Hash this, unsigned long hash)
{
void * found = TR_treeFind(this->tree, &hash, hashGetComp);
void * found = TR_treeFind(this->root, &hash, hashGetComp);
return found;
}

2
src/hash/get_first.c

@ -27,7 +27,7 @@
void *
TR_hashGetFirst(TR_Hash this)
{
return this->tree->root;
return this->root;
}
// vim: set ts=4 sw=4:

6
src/hash/hash.c

@ -31,10 +31,6 @@ static
int
hashCtor(void * _this, va_list * params)
{
TR_Hash this = _this;
this->tree = TR_new(TR_Tree);
return 0;
}
@ -45,8 +41,6 @@ hashDtor(void * _this)
TR_Hash this = _this;
TR_hashCleanup(this);
TR_delete(this->tree);
}
TR_INIT_IFACE(TR_Class, hashCtor, hashDtor, NULL);

13
src/queue/delete.c

@ -26,16 +26,9 @@
void
TR_queueDelete(TR_Queue this, void * msg)
{
TR_Queue node, parent;
pthread_mutex_lock(&(this->lock));
TR_Queue node, parent = TR_queueFindParent(this, msg);
parent = TR_queueFindParent(this, msg);
if (! parent) {
pthread_mutex_unlock(&(this->lock));
return;
}
if (! parent) return;
node = parent->next;
parent->next = node->next;
@ -47,8 +40,6 @@ TR_queueDelete(TR_Queue this, void * msg)
}
TR_delete(node);
this->nmsg--;
pthread_mutex_unlock(&(this->lock));
}
// vim: set ts=4 sw=4:

5
src/queue/destroy.c

@ -21,7 +21,6 @@
*/
#include <stdarg.h>
#include <pthread.h>
#include "trbase.h"
#include "tr/queue.h"
@ -31,8 +30,6 @@ TR_queueDestroy(TR_Queue this)
{
TR_Queue node = this->first;
pthread_mutex_lock(&(this->lock));
while (NULL != node) {
TR_Queue next = node->next;
if (this->free_msgs) {
@ -44,8 +41,6 @@ TR_queueDestroy(TR_Queue this)
this->first = this->next = this->last = NULL;
this->nmsg = 0;
pthread_mutex_unlock(&(this->lock));
}
// vim: set ts=4 sw=4:

7
src/queue/get.c

@ -20,8 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include "trbase.h"
#include "tr/queue.h"
@ -31,10 +29,7 @@ TR_queueGet(TR_Queue this)
TR_Queue first;
void * msg;
pthread_mutex_lock(&(this->lock));
if (NULL == this->first) {
pthread_mutex_unlock(&(this->lock));
return NULL;
}
@ -50,8 +45,6 @@ TR_queueGet(TR_Queue this)
this->first = first;
this->nmsg--;
pthread_mutex_unlock(&(this->lock));
return msg;
}

6
src/queue/put.c

@ -20,8 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include "trbase.h"
#include "tr/queue.h"
@ -30,8 +28,6 @@ TR_queuePut(TR_Queue this, void * msg)
{
TR_Queue node = (this->last)? this->last : this;
pthread_mutex_lock(&(this->lock));
node->next = TR_new(TR_Queue);
this->last = node->next;
@ -41,8 +37,6 @@ TR_queuePut(TR_Queue this, void * msg)
node->next->msg = msg;
this->nmsg++;
pthread_mutex_unlock(&(this->lock));
}
// vim: set ts=4 sw=4:

6
src/queue/put_first.c

@ -20,8 +20,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include "trbase.h"
#include "tr/queue.h"
@ -30,15 +28,11 @@ TR_queuePutFirst(TR_Queue this, void * msg)
{
TR_Queue current_first = this->first;
pthread_mutex_lock(&(this->lock));
this->first = this->next = TR_new(TR_Queue);
this->first->next = current_first;
this->first->msg = msg;
this->last = this->last ? this->last : this->first;
this->nmsg++;
pthread_mutex_unlock(&(this->lock));
}
// vim: set ts=4 sw=4:

7
src/queue/queue.c

@ -21,7 +21,6 @@
*/
#include <stdarg.h>
#include <pthread.h>
#include "trbase.h"
#include "tr/queue.h"
@ -33,7 +32,6 @@ queueCtor(void * _this, va_list * params)
TR_Queue this = _this;
this->free_msgs = 1;
pthread_mutex_init(&(this->lock), NULL);
return 0;
}
@ -42,10 +40,7 @@ static
void
queueDtor(void * _this)
{
TR_Queue this = _this;
TR_queueDestroy(this);
pthread_mutex_destroy(&(this->lock));
TR_queueDestroy((TR_Queue)_this);
}
TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);

1
src/tree/Makefile.am

@ -2,7 +2,6 @@ ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = subdir-objects
TREE = tree.c \
tree_node.c \
find.c \
insert.c \
delete.c \

29
src/tree/delete.c

@ -20,21 +20,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include "trbase.h"
#include "tr/tree.h"
void *
TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
TR_treeDelete(TR_Tree * this, const void * search, TR_TreeComp comp)
{
TR_TreeNode node = this->root;
TR_TreeNode del_node;
TR_TreeNode sibling;
int found;
void * data;
TR_Tree node = *this;
TR_Tree del_node;
TR_Tree sibling;
int found;
pthread_mutex_lock(&(this->lock));
void * data;
TR_TREE_FIND(node, search, found, comp);
@ -42,7 +39,6 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
* nothing was found...return NULL to indicate this.
*/
if (found != 0) {
pthread_mutex_unlock(&(this->lock));
return NULL;
}
@ -61,7 +57,7 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
* out inOrderSuccessor and remove the inOrderSuccessor.
*/
if (NULL != TR_TREE_LEFT(node) && NULL != TR_TREE_RIGHT(node)) {
TR_TreeNode successor;
TR_Tree successor;
TR_TREE_INORDER_SUCC(node, successor);
@ -70,12 +66,12 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
}
{
TR_TreeNode child = TR_TREE_CHILD(node);
TR_Tree child = TR_TREE_CHILD(node);
/*
* if we still have one child replace ourself with it.
*/
TR_TREE_REPLACE_NODE(&(this->root), node, child);
TR_TREE_REPLACE_NODE(this, node, child);
/*
* and finally delete the node...and prepare ourselfs
@ -85,7 +81,6 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
if (NULL != child && rbRed == child->color) {
child->color = rbBlack;
TR_delete(node);
pthread_mutex_unlock(&(this->lock));
return data;
} else {
del_node = node;
@ -99,7 +94,6 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
}
} else {
TR_delete(node);
pthread_mutex_unlock(&(this->lock));
return data;
}
}
@ -111,12 +105,9 @@ TR_treeDelete(TR_Tree this, const void * search, TR_TreeComp comp)
* rebalancing process...(this does not make much sense, but
* to be honest I don't know now.)
*/
TR_TREE_BALANCE_DELETE(&(this->root), node, sibling);
TR_TREE_BALANCE_DELETE(this, node, sibling);
TR_delete(del_node);
pthread_mutex_unlock(&(this->lock));
return data;
}

12
src/tree/destroy.c

@ -24,11 +24,11 @@
#include "tr/tree.h"
void
TR_treeDestroy(TR_Tree this, TR_TreeAction action)
TR_treeDestroy(TR_Tree * this, TR_TreeAction action)
{
TR_TreeNode previous = this->root;
TR_TreeNode node = this->root;
int depth = 1;
TR_Tree previous = * this;
TR_Tree node = * this;
int depth = 1;
/*
* I think this has something like O(n+log(n)) on a ballanced
@ -44,7 +44,7 @@ TR_treeDestroy(TR_Tree this, TR_TreeAction action)
|| previous == TR_TREE_LEFT(node)) && NULL == TR_TREE_RIGHT(node))
|| previous == TR_TREE_RIGHT(node)) {
TR_TreeNode parent = TR_TREE_PARENT(node);
TR_Tree parent = TR_TREE_PARENT(node);
if (action) {
action(node->data, NULL, depth);
@ -82,7 +82,7 @@ TR_treeDestroy(TR_Tree this, TR_TreeAction action)
}
}
this->root = NULL;
*this = NULL;
}
// vim: set ts=4 sw=4:

11
src/tree/find.c

@ -25,16 +25,11 @@
void *
TR_treeFind(TR_Tree this, const void * search, TR_TreeComp comp)
{
int found;
TR_TreeNode node = this->root;
int found;
pthread_mutex_lock(&(this->lock));
TR_TREE_FIND(this, search, found, comp);
TR_TREE_FIND(node, search, found, comp);
pthread_mutex_unlock(&(this->lock));
return found == 0 ? node->data : NULL;
return found == 0 ? this->data : NULL;
}
// vim: set ts=4 sw=4:

22
src/tree/insert.c

@ -20,20 +20,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pthread.h>
#include "trbase.h"
#include "tr/tree.h"
void *
TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
TR_treeInsert(TR_Tree * this, const void * search, TR_TreeComp comp)
{
TR_TreeNode node = this->root;
TR_TreeNode new_node = NULL;
TR_Tree node = *this;
TR_Tree new_node = NULL;
int found;
pthread_mutex_lock(&(this->lock));
/*
* insert the node or return the one in tree if comparison
* succeeds.
@ -43,13 +39,11 @@ TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
* if the root is NULL we simple add the element and set
* node to it.
*/
this->root = node = new_node = TR_new(TR_TreeNode, search);
*this = node = new_node = TR_new(TR_Tree, search);
} else {
TR_TREE_FIND(node, search, found, comp);
if (found == 0) {
pthread_mutex_unlock(&(this->lock));
// This differs from tsearch, which is the posix equivalent to
// this function in that it will not replace an existing value.
// If there is a value for the given key in the tree it will be
@ -61,11 +55,11 @@ TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
} else {
// not found
if (0 < found) {
node->left = TR_new(TR_TreeNode, search);
node->left = TR_new(TR_Tree, search);
node->left->parent = node;
node = new_node = node->left;
} else {
node->right = TR_new(TR_TreeNode, search);
node->right = TR_new(TR_Tree, search);
node->right->parent = node;
node = new_node = node->right;
}
@ -76,9 +70,7 @@ TR_treeInsert(TR_Tree this, const void * search, TR_TreeComp comp)
* we expect node not to be NULL and pointing to our
* new node at this point...now rabalance the tree
*/
TR_TREE_BALANCE_INSERT(&(this->root), node);
pthread_mutex_unlock(&(this->lock));
TR_TREE_BALANCE_INSERT(this, node);
return new_node->data;
}

9
src/tree/tree.c

@ -33,8 +33,11 @@ treeCtor(void * _this, va_list * params)
{
TR_Tree this = _this;
this->root = NULL;
pthread_mutex_init(&(this->lock), NULL);
this->data = va_arg(*params, void *);
this->color = rbRed;
this->parent = NULL;
this->left = NULL;
this->right = NULL;
return 0;
}
@ -43,8 +46,6 @@ static
void
treeDtor(void * _this)
{
TR_Tree this = _this;
pthread_mutex_destroy(&(this->lock));
}
TR_INIT_IFACE(TR_Class, treeCtor, treeDtor, NULL);

50
src/tree/tree_node.c

@ -1,50 +0,0 @@
/**
* \file
*
* \author Georg Hopp
*
* \copyright
* Copyright © 2014 Georg Hopp
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#define _GNU_SOURCE
#include <stdarg.h>
#include "trbase.h"
#include "tr/tree.h"
static
int
treeNodeCtor(void * _this, va_list * params)
{
TR_TreeNode this = _this;
this->data = va_arg(*params, void *);
this->color = rbRed;
this->parent = NULL;
this->left = NULL;
this->right = NULL;
return 0;
}
static void treeNodeDtor(void * _this) {}
TR_INIT_IFACE(TR_Class, treeNodeCtor, treeNodeDtor, NULL);
TR_CREATE_CLASS(TR_TreeNode, NULL, NULL, TR_IF(TR_Class));
// vim: set ts=4 sw=4:

6
src/tree/walk.c

@ -25,9 +25,9 @@
void
TR_treeWalk(TR_Tree this, const void * data, TR_TreeAction action)
{
TR_TreeNode previous = this->root;
TR_TreeNode node = this->root;
int depth = 1;
TR_Tree previous = this;
TR_Tree node = this;
int depth = 1;
while (NULL != node) {
if (previous == TR_TREE_RIGHT(node)) {

Loading…
Cancel
Save