bugfixed: must use lock when free_all_nodes
parent
edb8b2c4dd
commit
6d88bb980d
2
HISTORY
2
HISTORY
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
Version 1.44 2020-03-21
|
Version 1.44 2020-03-22
|
||||||
* add test file src/tests/test_pthread_lock.c
|
* add test file src/tests/test_pthread_lock.c
|
||||||
* add uniq_skiplist.[hc]
|
* add uniq_skiplist.[hc]
|
||||||
* add function split_string_ex
|
* add function split_string_ex
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,8 @@ int common_blocked_queue_push(struct common_blocked_queue *queue, void *data)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = (struct common_blocked_node *)fast_mblock_alloc_object(&queue->mblock);
|
node = (struct common_blocked_node *)fast_mblock_alloc_object(
|
||||||
|
&queue->mblock);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&(queue->lock));
|
pthread_mutex_unlock(&(queue->lock));
|
||||||
|
|
@ -202,9 +203,11 @@ void common_blocked_queue_free_all_nodes(struct common_blocked_queue *queue,
|
||||||
{
|
{
|
||||||
struct common_blocked_node *deleted;
|
struct common_blocked_node *deleted;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&(queue->lock));
|
||||||
while (node != NULL) {
|
while (node != NULL) {
|
||||||
deleted = node;
|
deleted = node;
|
||||||
node = node->next;
|
node = node->next;
|
||||||
fast_mblock_free_object(&queue->mblock, deleted);
|
fast_mblock_free_object(&queue->mblock, deleted);
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&(queue->lock));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ ALL_PRGS = test_allocator test_skiplist test_multi_skiplist test_mblock test_blo
|
||||||
test_id_generator test_ini_parser test_char_convert test_char_convert_loader \
|
test_id_generator test_ini_parser test_char_convert test_char_convert_loader \
|
||||||
test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \
|
test_logger test_skiplist_set test_crc32 test_thourands_seperator test_sched_thread \
|
||||||
test_json_parser test_pthread_lock test_uniq_skiplist test_split_string \
|
test_json_parser test_pthread_lock test_uniq_skiplist test_split_string \
|
||||||
test_server_id_func test_pipe
|
test_server_id_func test_pipe test_atomic
|
||||||
|
|
||||||
all: $(ALL_PRGS)
|
all: $(ALL_PRGS)
|
||||||
.c:
|
.c:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include "fastcommon/logger.h"
|
||||||
|
#include "fastcommon/shared_func.h"
|
||||||
|
#include "fastcommon/sched_thread.h"
|
||||||
|
#include "fastcommon/pthread_func.h"
|
||||||
|
#include "fastcommon/ini_file_reader.h"
|
||||||
|
#include "fastcommon/fast_allocator.h"
|
||||||
|
|
||||||
|
#define LOOP_COUNT (100 * 1000 * 1000)
|
||||||
|
#define barrier() __asm__ __volatile__("" ::: "memory")
|
||||||
|
|
||||||
|
static volatile int counter = 0;
|
||||||
|
|
||||||
|
#define THREAD_COUNT 9
|
||||||
|
pthread_t tids[THREAD_COUNT];
|
||||||
|
|
||||||
|
void *thread2_func(void *args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<LOOP_COUNT; i++) {
|
||||||
|
__sync_add_and_fetch(&counter, 1);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thread1_func(void *args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<LOOP_COUNT; i++) {
|
||||||
|
__sync_sub_and_fetch(&counter, 1);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *wait_thread_func(void *args)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<LOOP_COUNT; i++) {
|
||||||
|
__sync_add_and_fetch(&counter, 0);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int test()
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int i;
|
||||||
|
pthread_t *tid;
|
||||||
|
|
||||||
|
tid = tids;
|
||||||
|
for (i=0; i<THREAD_COUNT / 2; i++) {
|
||||||
|
if ((result=pthread_create(tid++, NULL, thread1_func, NULL)) != 0) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"create thread fail, "
|
||||||
|
"errno: %d, error info: %s",
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<THREAD_COUNT / 2; i++) {
|
||||||
|
if ((result=pthread_create(tid++, NULL, thread2_func, NULL)) != 0) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"create thread fail, "
|
||||||
|
"errno: %d, error info: %s",
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result=pthread_create(tid++, NULL, wait_thread_func, NULL)) != 0) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"create thread fail, "
|
||||||
|
"errno: %d, error info: %s",
|
||||||
|
__LINE__, result, STRERROR(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<THREAD_COUNT; i++) {
|
||||||
|
pthread_join(tids[i], NULL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int64_t start_time;
|
||||||
|
|
||||||
|
log_init();
|
||||||
|
srand(time(NULL));
|
||||||
|
g_log_context.log_level = LOG_DEBUG;
|
||||||
|
|
||||||
|
start_time = get_current_time_ms();
|
||||||
|
result = test();
|
||||||
|
printf("counter: %d, time used: %"PRId64" ms\n",
|
||||||
|
__sync_add_and_fetch(&counter, 0),
|
||||||
|
get_current_time_ms() - start_time);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue