diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:46:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:46:48 +0000 |
commit | 311bcfc6b3acdd6fd152798c7f287ddf74fa2a98 (patch) | |
tree | 0ec307299b1dada3701e42f4ca6eda57d708261e /src/interfaces/ecpg/test/thread | |
parent | Initial commit. (diff) | |
download | postgresql-15-upstream.tar.xz postgresql-15-upstream.zip |
Adding upstream version 15.4.upstream/15.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/interfaces/ecpg/test/thread')
-rw-r--r-- | src/interfaces/ecpg/test/thread/.gitignore | 10 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/Makefile | 13 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/alloc.pgc | 90 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/descriptor.pgc | 68 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/prep.pgc | 96 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/thread.pgc | 136 | ||||
-rw-r--r-- | src/interfaces/ecpg/test/thread/thread_implicit.pgc | 136 |
7 files changed, 549 insertions, 0 deletions
diff --git a/src/interfaces/ecpg/test/thread/.gitignore b/src/interfaces/ecpg/test/thread/.gitignore new file mode 100644 index 0000000..12ff319 --- /dev/null +++ b/src/interfaces/ecpg/test/thread/.gitignore @@ -0,0 +1,10 @@ +/alloc +/alloc.c +/descriptor +/descriptor.c +/prep +/prep.c +/thread +/thread.c +/thread_implicit +/thread_implicit.c diff --git a/src/interfaces/ecpg/test/thread/Makefile b/src/interfaces/ecpg/test/thread/Makefile new file mode 100644 index 0000000..1b4ddcf --- /dev/null +++ b/src/interfaces/ecpg/test/thread/Makefile @@ -0,0 +1,13 @@ +subdir = src/interfaces/ecpg/test/thread +top_builddir = ../../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/$(subdir)/../Makefile.regress + + +TESTS = thread_implicit thread_implicit.c \ + thread thread.c \ + prep prep.c \ + descriptor descriptor.c \ + alloc alloc.c + +all: $(TESTS) diff --git a/src/interfaces/ecpg/test/thread/alloc.pgc b/src/interfaces/ecpg/test/thread/alloc.pgc new file mode 100644 index 0000000..c0021a7 --- /dev/null +++ b/src/interfaces/ecpg/test/thread/alloc.pgc @@ -0,0 +1,90 @@ +#include <stdint.h> +#include <stdlib.h> +#include "ecpg_config.h" + +#ifndef ENABLE_THREAD_SAFETY +int +main(void) +{ + printf("No threading enabled.\n"); + return 0; +} +#else +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <process.h> +#include <locale.h> +#else +#include <pthread.h> +#endif +#include <stdio.h> + +#define THREADS 16 +#define REPEATS 50 + +exec sql include sqlca; +exec sql include ../regression; + +exec sql whenever sqlerror sqlprint; +exec sql whenever not found sqlprint; + +#ifdef WIN32 +static unsigned __stdcall fn(void* arg) +#else +static void* fn(void* arg) +#endif +{ + int i; + + EXEC SQL BEGIN DECLARE SECTION; + int value; + char name[100]; + char **r = NULL; + EXEC SQL END DECLARE SECTION; + + value = (intptr_t) arg; + sprintf(name, "Connection: %d", value); + + EXEC SQL CONNECT TO REGRESSDB1 AS :name; + EXEC SQL SET AUTOCOMMIT TO ON; + for (i = 1; i <= REPEATS; ++i) + { + EXEC SQL SELECT relname INTO :r FROM pg_class WHERE relname = 'pg_class'; + free(r); + r = NULL; + } + EXEC SQL DISCONNECT :name; + + return 0; +} + +int main () +{ + intptr_t i; +#ifdef WIN32 + HANDLE threads[THREADS]; +#else + pthread_t threads[THREADS]; +#endif + +#ifdef WIN32 + for (i = 0; i < THREADS; ++i) + { + unsigned id; + threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id); + } + + WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE); + for (i = 0; i < THREADS; ++i) + CloseHandle(threads[i]); +#else + for (i = 0; i < THREADS; ++i) + pthread_create(&threads[i], NULL, fn, (void *) i); + for (i = 0; i < THREADS; ++i) + pthread_join(threads[i], NULL); +#endif + + return 0; +} +#endif diff --git a/src/interfaces/ecpg/test/thread/descriptor.pgc b/src/interfaces/ecpg/test/thread/descriptor.pgc new file mode 100644 index 0000000..76a7a5d --- /dev/null +++ b/src/interfaces/ecpg/test/thread/descriptor.pgc @@ -0,0 +1,68 @@ +#ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <process.h> +#include <locale.h> +#else +#include <pthread.h> +#endif +#endif +#include <stdio.h> + +#define THREADS 16 +#define REPEATS 50000 + +EXEC SQL include sqlca; +EXEC SQL whenever sqlerror sqlprint; +EXEC SQL whenever not found sqlprint; + +#if defined(ENABLE_THREAD_SAFETY) && defined(WIN32) +static unsigned __stdcall fn(void* arg) +#else +static void* fn(void* arg) +#endif +{ + int i; + + for (i = 1; i <= REPEATS; ++i) + { + EXEC SQL ALLOCATE DESCRIPTOR mydesc; + EXEC SQL DEALLOCATE DESCRIPTOR mydesc; + } + + return 0; +} + +int main () +{ +#ifdef ENABLE_THREAD_SAFETY + int i; +#ifdef WIN32 + HANDLE threads[THREADS]; +#else + pthread_t threads[THREADS]; +#endif + +#ifdef WIN32 + for (i = 0; i < THREADS; ++i) + { + unsigned id; + threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, NULL, 0, &id); + } + + WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE); + for (i = 0; i < THREADS; ++i) + CloseHandle(threads[i]); +#else + for (i = 0; i < THREADS; ++i) + pthread_create(&threads[i], NULL, fn, NULL); + for (i = 0; i < THREADS; ++i) + pthread_join(threads[i], NULL); +#endif +#else + fn(NULL); +#endif + + return 0; +} diff --git a/src/interfaces/ecpg/test/thread/prep.pgc b/src/interfaces/ecpg/test/thread/prep.pgc new file mode 100644 index 0000000..d7ecfd4 --- /dev/null +++ b/src/interfaces/ecpg/test/thread/prep.pgc @@ -0,0 +1,96 @@ +#include <stdint.h> +#include <stdlib.h> +#include "ecpg_config.h" + +#ifndef ENABLE_THREAD_SAFETY +int +main(void) +{ + printf("No threading enabled.\n"); + return 0; +} +#else +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <process.h> +#include <locale.h> +#else +#include <pthread.h> +#endif +#include <stdio.h> + +#define THREADS 16 +#define REPEATS 50 + +exec sql include sqlca; +exec sql include ../regression; + +exec sql whenever sqlerror sqlprint; +exec sql whenever not found sqlprint; + +#ifdef WIN32 +static unsigned __stdcall fn(void* arg) +#else +static void* fn(void* arg) +#endif +{ + int i; + + EXEC SQL BEGIN DECLARE SECTION; + int value; + char name[100]; + char query[256] = "INSERT INTO T VALUES ( ? )"; + EXEC SQL END DECLARE SECTION; + + value = (intptr_t) arg; + sprintf(name, "Connection: %d", value); + + EXEC SQL CONNECT TO REGRESSDB1 AS :name; + EXEC SQL SET AUTOCOMMIT TO ON; + for (i = 1; i <= REPEATS; ++i) + { + EXEC SQL PREPARE I FROM :query; + EXEC SQL EXECUTE I USING :value; + } + EXEC SQL DEALLOCATE I; + EXEC SQL DISCONNECT :name; + + return 0; +} + +int main () +{ + intptr_t i; +#ifdef WIN32 + HANDLE threads[THREADS]; +#else + pthread_t threads[THREADS]; +#endif + + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL SET AUTOCOMMIT TO ON; + EXEC SQL DROP TABLE IF EXISTS T; + EXEC SQL CREATE TABLE T ( i int ); + EXEC SQL DISCONNECT; + +#ifdef WIN32 + for (i = 0; i < THREADS; ++i) + { + unsigned id; + threads[i] = (HANDLE)_beginthreadex(NULL, 0, fn, (void*)i, 0, &id); + } + + WaitForMultipleObjects(THREADS, threads, TRUE, INFINITE); + for (i = 0; i < THREADS; ++i) + CloseHandle(threads[i]); +#else + for (i = 0; i < THREADS; ++i) + pthread_create(&threads[i], NULL, fn, (void *) i); + for (i = 0; i < THREADS; ++i) + pthread_join(threads[i], NULL); +#endif + + return 0; +} +#endif diff --git a/src/interfaces/ecpg/test/thread/thread.pgc b/src/interfaces/ecpg/test/thread/thread.pgc new file mode 100644 index 0000000..e7d8c00 --- /dev/null +++ b/src/interfaces/ecpg/test/thread/thread.pgc @@ -0,0 +1,136 @@ +/* + * Thread test program + * by Philip Yarra & Lee Kindness. + */ +#include <stdint.h> +#include <stdlib.h> +#include "ecpg_config.h" + +#ifndef ENABLE_THREAD_SAFETY +int +main(void) +{ + printf("No threading enabled.\n"); + return 0; +} +#else +#ifndef WIN32 +#include <pthread.h> +#else +#include <windows.h> +#include <locale.h> +#endif + +exec sql include ../regression; + +void *test_thread(void *arg); + +int nthreads = 10; +int iterations = 20; + +int main() +{ +#ifndef WIN32 + pthread_t *threads; +#else + HANDLE *threads; +#endif + intptr_t n; + EXEC SQL BEGIN DECLARE SECTION; + int l_rows; + EXEC SQL END DECLARE SECTION; + + /* Do not switch on debug output for regression tests. The threads get executed in + * more or less random order */ + /* ECPGdebug(1, stderr); */ + + /* setup test_thread table */ + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL DROP TABLE test_thread; /* DROP might fail */ + EXEC SQL COMMIT; + EXEC SQL CREATE TABLE + test_thread(tstamp TIMESTAMP NOT NULL DEFAULT CAST(timeofday() AS TIMESTAMP), + thread TEXT NOT NULL, + iteration INTEGER NOT NULL, + PRIMARY KEY(thread, iteration)); + EXEC SQL COMMIT; + EXEC SQL DISCONNECT; + + /* create, and start, threads */ + threads = calloc(nthreads, sizeof(threads[0])); + if( threads == NULL ) + { + fprintf(stderr, "Cannot alloc memory\n"); + return 1; + } + for( n = 0; n < nthreads; n++ ) + { +#ifndef WIN32 + pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1)); +#else + threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n + 1), 0, NULL); +#endif + } + + /* wait for thread completion */ +#ifndef WIN32 + for( n = 0; n < nthreads; n++ ) + { + pthread_join(threads[n], NULL); + } +#else + WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE); +#endif + free(threads); + + /* and check results */ + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL SELECT COUNT(*) INTO :l_rows FROM test_thread; + EXEC SQL COMMIT; + EXEC SQL DISCONNECT; + if( l_rows == (nthreads * iterations) ) + printf("Success.\n"); + else + printf("ERROR: Failure - expecting %d rows, got %d.\n", nthreads * iterations, l_rows); + + return 0; +} + +void *test_thread(void *arg) +{ + long threadnum = (intptr_t) arg; + + EXEC SQL BEGIN DECLARE SECTION; + int l_i; + char l_connection[128]; + EXEC SQL END DECLARE SECTION; + + /* build up connection name, and connect to database */ +#ifndef _MSC_VER + snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#else + _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#endif + EXEC SQL WHENEVER sqlerror sqlprint; + EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection; + if( sqlca.sqlcode != 0 ) + { + printf("%s: ERROR: cannot connect to database!\n", l_connection); + return NULL; + } + EXEC SQL AT :l_connection BEGIN; + + /* insert into test_thread table */ + for( l_i = 1; l_i <= iterations; l_i++ ) + { + EXEC SQL AT :l_connection INSERT INTO test_thread(thread, iteration) VALUES(:l_connection, :l_i); + if( sqlca.sqlcode != 0 ) + printf("%s: ERROR: insert failed!\n", l_connection); + } + + /* all done */ + EXEC SQL AT :l_connection COMMIT; + EXEC SQL DISCONNECT :l_connection; + return NULL; +} +#endif /* ENABLE_THREAD_SAFETY */ diff --git a/src/interfaces/ecpg/test/thread/thread_implicit.pgc b/src/interfaces/ecpg/test/thread/thread_implicit.pgc new file mode 100644 index 0000000..b4cae7e --- /dev/null +++ b/src/interfaces/ecpg/test/thread/thread_implicit.pgc @@ -0,0 +1,136 @@ +/* + * Thread test program + * by Lee Kindness. + */ +#include <stdint.h> +#include <stdlib.h> +#include "ecpg_config.h" + +#ifndef ENABLE_THREAD_SAFETY +int +main(void) +{ + printf("No threading enabled.\n"); + return 0; +} +#else +#ifndef WIN32 +#include <pthread.h> +#else +#include <windows.h> +#include <locale.h> +#endif + +exec sql include ../regression; + +void *test_thread(void *arg); + +int nthreads = 10; +int iterations = 20; + +int main() +{ +#ifndef WIN32 + pthread_t *threads; +#else + HANDLE *threads; +#endif + intptr_t n; + EXEC SQL BEGIN DECLARE SECTION; + int l_rows; + EXEC SQL END DECLARE SECTION; + + /* Do not switch on debug output for regression tests. The threads get executed in + * more or less random order */ + /* ECPGdebug(1, stderr); */ + + /* setup test_thread table */ + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL DROP TABLE test_thread; /* DROP might fail */ + EXEC SQL COMMIT; + EXEC SQL CREATE TABLE + test_thread(tstamp TIMESTAMP NOT NULL DEFAULT CAST(timeofday() AS TIMESTAMP), + thread TEXT NOT NULL, + iteration INTEGER NOT NULL, + PRIMARY KEY(thread, iteration)); + EXEC SQL COMMIT; + EXEC SQL DISCONNECT; + + /* create, and start, threads */ + threads = calloc(nthreads, sizeof(threads[0])); + if( threads == NULL ) + { + fprintf(stderr, "Cannot alloc memory\n"); + return 1; + } + for( n = 0; n < nthreads; n++ ) + { +#ifndef WIN32 + pthread_create(&threads[n], NULL, test_thread, (void *) (n + 1)); +#else + threads[n] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) (void (*) (void)) test_thread, (void *) (n+1), 0, NULL); +#endif + } + + /* wait for thread completion */ +#ifndef WIN32 + for( n = 0; n < nthreads; n++ ) + { + pthread_join(threads[n], NULL); + } +#else + WaitForMultipleObjects(nthreads, threads, TRUE, INFINITE); +#endif + free(threads); + + /* and check results */ + EXEC SQL CONNECT TO REGRESSDB1; + EXEC SQL SELECT COUNT(*) INTO :l_rows FROM test_thread; + EXEC SQL COMMIT; + EXEC SQL DISCONNECT; + if( l_rows == (nthreads * iterations) ) + printf("Success.\n"); + else + printf("ERROR: Failure - expecting %d rows, got %d.\n", nthreads * iterations, l_rows); + + return 0; +} + +void *test_thread(void *arg) +{ + long threadnum = (intptr_t) arg; + + EXEC SQL BEGIN DECLARE SECTION; + int l_i; + char l_connection[128]; + EXEC SQL END DECLARE SECTION; + + /* build up connection name, and connect to database */ +#ifndef _MSC_VER + snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#else + _snprintf(l_connection, sizeof(l_connection), "thread_%03ld", threadnum); +#endif + EXEC SQL WHENEVER sqlerror sqlprint; + EXEC SQL CONNECT TO REGRESSDB1 AS :l_connection; + if( sqlca.sqlcode != 0 ) + { + printf("%s: ERROR: cannot connect to database!\n", l_connection); + return NULL; + } + EXEC SQL BEGIN; + + /* insert into test_thread table */ + for( l_i = 1; l_i <= iterations; l_i++ ) + { + EXEC SQL INSERT INTO test_thread(thread, iteration) VALUES(:l_connection, :l_i); + if( sqlca.sqlcode != 0 ) + printf("%s: ERROR: insert failed!\n", l_connection); + } + + /* all done */ + EXEC SQL COMMIT; + EXEC SQL DISCONNECT :l_connection; + return NULL; +} +#endif /* ENABLE_THREAD_SAFETY */ |