*** ./pgsql/src/backend/Makefile.orig Mon Feb 18 11:05:00 2002 --- ./pgsql/src/backend/Makefile Mon Feb 18 11:04:50 2002 *************** *** 14,20 **** DIRS := access bootstrap catalog parser commands executor lib libpq \ main nodes optimizer port postmaster regex rewrite \ ! storage tcop utils OBJS := $(DIRS:%=%/SUBSYS.o) --- 14,20 ---- DIRS := access bootstrap catalog parser commands executor lib libpq \ main nodes optimizer port postmaster regex rewrite \ ! storage tcop utils env OBJS := $(DIRS:%=%/SUBSYS.o) *** ./pgsql/src/backend/env/Makefile.orig Mon Feb 18 11:11:28 2002 --- ./pgsql/src/backend/env/Makefile Mon Feb 18 11:11:01 2002 *************** *** 0 **** --- 1,29 ---- + #------------------------------------------------------------------------- + # + # Makefile-- + # Makefile for env + # + # IDENTIFICATION + # + #------------------------------------------------------------------------- + + subdir = src/backend/env + top_builddir = ../../.. + include $(top_builddir)/src/Makefile.global + + OBJS= env.o thread.o + + all: SUBSYS.o + + SUBSYS.o: $(OBJS) + $(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS) + + depend dep: + $(CC) -MM $(CFLAGS) *.c >depend + + clean: + rm -f SUBSYS.o $(OBJS) + + ifeq (depend,$(wildcard depend)) + include depend + endif *** ./pgsql/src/backend/env/env.c.orig Mon Feb 18 10:56:52 2002 --- ./pgsql/src/backend/env/env.c Tue Feb 19 08:35:31 2002 *************** *** 0 **** --- 1,231 ---- + /*------------------------------------------------------------------------- + * + * env.c + * setup and maintain global connection environment + * + * + *------------------------------------------------------------------------- + */ + #ifdef PG_THREADS + #include + #endif + + + #include "postgres.h" + #include "env/env.h" + #include "env/thread.h" + + typedef HTAB* PGEnv; + + #ifdef PG_THREADS + + static int envcount; + static int envlimit; + static pthread_key_t* envkey; + static PGEnv* envmap; + static ThreadMutex envlock; + + #else + + static PGEnv single_env; + + #endif + + #define INITENVCACHESIZE 20 + + typedef struct global_env_entry { + SectionId env_id; + void* global_pointer; + int global_size; + } EnvEntry; + + static PGEnv CreateEnv(void); + static PGEnv GetEnv(void); + static void SetEnv(PGEnv env); + + + int InitGlobalEnvironment(bool isPrivate,int maxbackends) + { + int retcode = 0; + #ifdef PG_THREADS + envlimit = maxbackends; + /* initialize envronment storage structures and locking */ + envlock = CreateProcessMutex(); + /* envlock init with default attributes (process scope) */ + envmap = malloc(sizeof(PGEnv) * maxbackends); + + envcount = 0; + for (counter=0;counterglobal_size >0 ) { + free(entry->global_pointer); + entry->global_pointer = NULL; + entry->global_size = 0; + free(entry); + } + } + free(list->tabname); + free(list); + #ifdef PG_THREADS + PGEnv* map = (PGEnv*)pthread_getspecific(*envkey); + + if ( map != NULL ) *map = NULL; + envcount--; + #else /* PG_THREADS */ + single_env = NULL; + #endif /* PG_THREADS */ + return 0; + } + + + void* AllocateEnvSpace(SectionId id,int size) + { + PGEnv env = GetEnv(); + bool found = FALSE; + EnvEntry* entry; + + if ( env == NULL ) { + elog(FATAL,"no global environment"); + } + + entry = hash_search(env,&id,HASH_ENTER,&found); + if ( found ) { + elog(FATAL,"environment space already created"); + } else { + entry->global_pointer = malloc(size); + entry->global_size = size; + } + return entry->global_pointer; + } + + int ReleaseEnvSpace(SectionId id) + { + PGEnv env = GetEnv(); + bool found =FALSE; + + if ( env == NULL ) { + elog(FATAL,"no global environment"); + } + hash_search(env,&id,HASH_REMOVE,&found); + return 0; + } + + void* GetEnvSpace(SectionId id) + { + PGEnv env = GetEnv(); + bool found =FALSE; + EnvEntry* entry; + + if ( env == NULL ) { + elog(FATAL,"no global environment"); + } + + entry = (EnvEntry*)hash_search(env,&id,HASH_ENTER,&found); + if ( !found ) { + elog(FATAL,"environment space does not exist"); + } + + return entry->global_pointer; + } + *** ./pgsql/src/backend/utils/hash/dynahash.c.orig Mon Feb 18 08:44:17 2002 --- ./pgsql/src/backend/utils/hash/dynahash.c Tue Feb 19 08:41:40 2002 *************** *** 105,132 **** { HTAB *hashp; HASHHDR *hctl; /* First time through, create a memory context for hash tables */ ! if (!DynaHashCxt) ! DynaHashCxt = AllocSetContextCreate(TopMemoryContext, "DynaHash", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); ! ! /* Select allocation context for this hash table */ ! if (flags & HASH_CONTEXT) ! CurrentDynaHashCxt = info->hcxt; ! else CurrentDynaHashCxt = DynaHashCxt; /* Initialize the hash header */ ! hashp = (HTAB *) MEM_ALLOC(sizeof(HTAB)); if (!hashp) return NULL; MemSet(hashp, 0, sizeof(HTAB)); ! hashp->tabname = (char *) MEM_ALLOC(strlen(tabname) + 1); strcpy(hashp->tabname, tabname); if (flags & HASH_FUNCTION) --- 105,144 ---- { HTAB *hashp; HASHHDR *hctl; + void *(*h_alloc) (Size); + /* set the allocation method early so all structures + * for the hashtable use the designated allocation method + * if set. This is needed to use global environment for + * thread safety and seems more accurate MKS 2.18.2002 + */ + if (flags & HASH_ALLOC) { + h_alloc = info->alloc; + } else { + h_alloc = MEM_ALLOC; + } + /* Select allocation context for this hash table */ + if (flags & HASH_CONTEXT) { + CurrentDynaHashCxt = info->hcxt; + } else { /* First time through, create a memory context for hash tables */ ! if (!DynaHashCxt) { ! DynaHashCxt = AllocSetContextCreate(TopMemoryContext, "DynaHash", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); ! } CurrentDynaHashCxt = DynaHashCxt; + } /* Initialize the hash header */ ! hashp = (HTAB *) h_alloc(sizeof(HTAB)); if (!hashp) return NULL; MemSet(hashp, 0, sizeof(HTAB)); ! hashp->tabname = (char *) h_alloc(strlen(tabname) + 1); strcpy(hashp->tabname, tabname); if (flags & HASH_FUNCTION) *************** *** 155,161 **** /* setup hash table defaults */ hashp->hctl = NULL; hashp->dir = NULL; ! hashp->alloc = MEM_ALLOC; hashp->hcxt = DynaHashCxt; hashp->isshared = false; } --- 167,173 ---- /* setup hash table defaults */ hashp->hctl = NULL; hashp->dir = NULL; ! hashp->alloc = h_alloc; hashp->hcxt = DynaHashCxt; hashp->isshared = false; } *** ./pgsql/src/backend/utils/mmgr/mcxt.c.orig Wed Oct 24 22:49:51 2001 --- ./pgsql/src/backend/utils/mmgr/mcxt.c Sat Feb 9 05:06:51 2002 *************** *** 21,26 **** --- 21,27 ---- #include "postgres.h" + #include "env/env.h" #include "nodes/memnodes.h" #include "utils/excid.h" #include "utils/memutils.h" *************** *** 29,35 **** /***************************************************************************** * GLOBAL MEMORY * *****************************************************************************/ ! /* * CurrentMemoryContext * Default memory context for allocations. --- 30,36 ---- /***************************************************************************** * GLOBAL MEMORY * *****************************************************************************/ ! #ifndef USE_GLOBAL_ENVIRONMENT /* * CurrentMemoryContext * Default memory context for allocations. *************** *** 46,52 **** MemoryContext QueryContext = NULL; MemoryContext TopTransactionContext = NULL; MemoryContext TransactionCommandContext = NULL; ! /***************************************************************************** * EXPORTED ROUTINES * --- 47,55 ---- MemoryContext QueryContext = NULL; MemoryContext TopTransactionContext = NULL; MemoryContext TransactionCommandContext = NULL; ! #else ! static SectionId mem_section_id = ('M' << 24 ) | ('C' << 16 ) | ('X' << 8 ) | ('T'); ! #endif /***************************************************************************** * EXPORTED ROUTINES * *************** *** 71,76 **** --- 74,82 ---- void MemoryContextInit(void) { + #ifdef USE_GLOBAL_ENVIRONMENT + MemoryContextInitEnv(); + #endif AssertState(TopMemoryContext == NULL); /* *************** *** 105,110 **** --- 111,137 ---- 8 * 1024, 8 * 1024); } + + #ifdef USE_GLOBAL_ENVIRONMENT + void + MemoryContextInitEnv(void) + { + void* mem = (MemoryContextGlobals*)AllocateEnvSpace(mem_section_id,sizeof(MemoryContextGlobals)); + MemSet(mem,0x00,sizeof(MemoryContextGlobals)); + } + + void + MemoryContextDestroyEnv(void) + { + ReleaseEnvSpace(mem_section_id); + } + + MemoryContextGlobals* + MemoryContextGetEnv(void) + { + return (MemoryContextGlobals*)GetEnvSpace(mem_section_id); + } + #endif /* USE_GLOBAL_ENVIRONMENT */ /* * MemoryContextReset *** ./pgsql/src/include/env/env.h.orig Mon Feb 18 10:31:26 2002 --- ./pgsql/src/include/env/env.h Mon Feb 18 11:13:36 2002 *************** *** 0 **** --- 1,42 ---- + + /*------------------------------------------------------------------------- + * + * env.h + * encapsulate all global variables + * in an environment for threads inplementation + * MKS 2.8.2002 + *------------------------------------------------------------------------- + */ + + #ifndef __ENV_H__ + #define __ENV_H__ + + #ifdef PG_THREADS + #include + #endif + + #include "postgres.h" + + #include "utils/hsearch.h" + + + #ifdef PG_THREADS + /* defined in env.c */ + extern DLLIMPORT pthread_condattr_t* process_cond_attr; + extern DLLIMPORT pthread_mutexattr_t* process_mutex_attr; + #endif + + typedef int SectionId; + + int InitGlobalEnvironment(bool isPrivate,int maxbackends); + int DestroyGlobalEnvironment(void); + + int ReleaseCurrentEnv(void); + + void* AllocateEnvSpace(int id,int size); + int ReleaseEnvSpace(int id); + void* GetEnvSpace(int id); + + #endif + + *** ./pgsql/src/include/env/thread.h.orig Mon Feb 18 11:12:10 2002 --- ./pgsql/src/include/env/thread.h Mon Feb 18 11:46:57 2002 *************** *** 0 **** --- 1,45 ---- + + /*------------------------------------------------------------------------- + * + * thread.h + * threads implementation and interface. + * create abstraction layer for pthreads + * + * MKS 2.8.2002 + *------------------------------------------------------------------------- + */ + + #ifndef __THREAD_H__ + #define __THREAD_H__ + + #include + + #include "postgres.h" + + typedef pthread_mutex_t* ThreadMutex; + typedef pthread_cond_t* ThreadCond; + typedef pthread_t Thread; + + ThreadMutex CreateProcessMutex(void); + ThreadMutex CreateSystemMutex(void); + ThreadCond CreateProcessCond(void); + ThreadCond CreateSystemCond(void); + + int DestroyMutex(ThreadMutex mutex); + int DestroyCond(ThreadCond cond); + + Thread CreateThread(int priority); + Thread CreateDaemonThread(int priority); + int ThreadJoin(Thread t); + + int MutexLock(ThreadMutex mutex); + int MutexUnlock(ThreadMutex mutex); + int MutexTryLock(ThreadMutex mutex); + + int CondWait(ThreadCond cond); + int CondTryWait(ThreadCond cond); + int CondSignal(ThreadCond cond); + int CondBroadcast(ThreadCond cond); + + + #endif /* __THREAD_H__ */ *** ./pgsql/src/include/utils/catcache.h.orig Mon Feb 18 10:55:00 2002 --- ./pgsql/src/include/utils/catcache.h Sat Feb 9 04:39:22 2002 *************** *** 81,87 **** --- 81,89 ---- /* this extern duplicates utils/memutils.h... */ + #ifndef USE_GLOBAL_ENVIRONMENT extern MemoryContext CacheMemoryContext; + #endif extern void CreateCacheMemoryContext(void); extern void AtEOXact_CatCache(bool isCommit); *** ./pgsql/src/include/utils/memutils.h.orig Mon Nov 5 09:46:36 2001 --- ./pgsql/src/include/utils/memutils.h Sat Feb 9 07:21:53 2002 *************** *** 64,69 **** --- 64,70 ---- * Only TopMemoryContext and ErrorContext are initialized by * MemoryContextInit() itself. */ + #ifndef USE_GLOBAL_ENVIRONMENT extern DLLIMPORT MemoryContext TopMemoryContext; extern DLLIMPORT MemoryContext ErrorContext; extern DLLIMPORT MemoryContext PostmasterContext; *************** *** 71,82 **** extern DLLIMPORT MemoryContext QueryContext; extern DLLIMPORT MemoryContext TopTransactionContext; extern DLLIMPORT MemoryContext TransactionCommandContext; ! /* * Memory-context-type-independent functions in mcxt.c */ extern void MemoryContextInit(void); extern void MemoryContextReset(MemoryContext context); extern void MemoryContextDelete(MemoryContext context); extern void MemoryContextResetChildren(MemoryContext context); --- 72,95 ---- extern DLLIMPORT MemoryContext QueryContext; extern DLLIMPORT MemoryContext TopTransactionContext; extern DLLIMPORT MemoryContext TransactionCommandContext; ! #else ! #define TopMemoryContext MemoryContextGetEnv()->WrappedTopMemoryCxt ! #define ErrorContext MemoryContextGetEnv()->WrappedErrorCxt ! #define PostmasterContext MemoryContextGetEnv()->WrappedPostmasterCxt ! #define CacheMemoryContext MemoryContextGetEnv()->WrappedCacheMemoryCxt ! #define QueryContext MemoryContextGetEnv()->WrappedQueryCxt ! #define TopTransactionContext MemoryContextGetEnv()->WrappedTopTransactionCxt ! #define TransactionCommandContext MemoryContextGetEnv()->WrappedTransactionCommandCxt ! #endif /* * Memory-context-type-independent functions in mcxt.c */ extern void MemoryContextInit(void); + #ifdef USE_GLOBAL_ENVIRONMENT + extern void MemoryContextInitEnv(void); + extern void MemoryContextDestroyEnv(void); + #endif extern void MemoryContextReset(MemoryContext context); extern void MemoryContextDelete(MemoryContext context); extern void MemoryContextResetChildren(MemoryContext context); *** ./pgsql/src/include/utils/palloc.h.orig Mon Nov 5 09:46:36 2001 --- ./pgsql/src/include/utils/palloc.h Sat Feb 9 07:36:07 2002 *************** *** 40,53 **** * We declare it here so that palloc() can be a macro. Avoid accessing it * directly! Instead, use MemoryContextSwitchTo() to change the setting. */ - extern DLLIMPORT MemoryContext CurrentMemoryContext; - /* * Fundamental memory-allocation operations (more are in utils/memutils.h) */ extern void *MemoryContextAlloc(MemoryContext context, Size size); #define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) extern void pfree(void *pointer); --- 40,75 ---- * We declare it here so that palloc() can be a macro. Avoid accessing it * directly! Instead, use MemoryContextSwitchTo() to change the setting. */ /* * Fundamental memory-allocation operations (more are in utils/memutils.h) */ extern void *MemoryContextAlloc(MemoryContext context, Size size); + #ifndef USE_GLOBAL_ENVIRONMENT + + extern DLLIMPORT MemoryContext CurrentMemoryContext; + #define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) + + #else /* USE_GLOBAL_ENVIRONMENT */ + + typedef struct mem_manager_globals { + MemoryContext WrappedCurrentMemoryCxt; + MemoryContext WrappedTopMemoryCxt; + MemoryContext WrappedErrorCxt; + MemoryContext WrappedPostmasterCxt; + MemoryContext WrappedCacheMemoryCxt; + MemoryContext WrappedQueryCxt; + MemoryContext WrappedTopTransactionCxt; + MemoryContext WrappedTransactionCommandCxt; + } MemoryContextGlobals; + #define CurrentMemoryContext MemoryContextGetEnv()->WrappedCurrentMemoryCxt + + extern MemoryContextGlobals* MemoryContextGetEnv(void); + + #define palloc(sz) MemoryContextAlloc(MemoryContextGetEnv()->WrappedCurrentMemoryCxt, (sz)) + + #endif /* USE_GLOBAL_ENVIRONMENT */ extern void pfree(void *pointer);