*** 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 Wed Feb 27 01:45:48 2002 *************** *** 0 **** --- 1,256 ---- + /*------------------------------------------------------------------------- + * + * env.c + * setup and maintain global connection environment + * + * + *------------------------------------------------------------------------- + */ + #ifdef PG_THREADS + #include + #endif + + + #include "postgres.h" + #include "env/env.h" + #include "env/thread.h" + #include "nodes/memnodes.h" + #include "utils/memutils.h" + + typedef struct env { + MemoryContext GlobalContext; + HTAB* GlobalsHash; + } PGEnvData; + + typedef PGEnvData* 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;counterGlobalContext = AllocSetContextCreate((MemoryContext) NULL, + "GlobalContext", + 8 * 1024, + 8 * 1024, + 8 * 1024); + MemSet(&ctl, 0, (int) sizeof(ctl)); + ctl.keysize = sizeof(SectionId); + ctl.entrysize = sizeof(EnvEntry); + ctl.hash = tag_hash; + ctl.hcxt = newenv->GlobalContext; + + newenv->GlobalsHash = hash_create("Env global lookup", + INITENVCACHESIZE, + &ctl, + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + + SetEnv(newenv); + return newenv; + } + + int ReleaseCurrentEnv(void) + { + PGEnv list = GetEnv(); + + /* deleting the MemoryContext should free all global memory + * and doesn't know how to free this hashtable MKS 2.18.2002 + */ + MemoryContextResetAndDeleteChildren(list->GlobalContext); + /* + Must free the actual context because it was created + with NULL parent context which creates a malloc'd + MemoryContext. MKS 2.26.2002 + */ + free(list->GlobalContext); + 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->GlobalsHash,&id,HASH_ENTER,&found); + if ( found ) { + elog(FATAL,"environment space already created"); + } else { + entry->global_pointer = MemoryContextAlloc(env->GlobalContext,size); + entry->global_size = size; + MemSet(entry->global_pointer,0x00,size); + } + return entry->global_pointer; + } + + int ReleaseEnvSpace(SectionId id) + { + PGEnv env = GetEnv(); + bool found =FALSE; + EnvEntry* entry; + + if ( env == NULL ) { + elog(FATAL,"no global environment"); + } + entry = hash_search(env->GlobalsHash,&id,HASH_REMOVE,&found); + pfree(entry->global_pointer); + + 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->GlobalsHash,&id,HASH_FIND,&found); + if ( !found ) { + elog(FATAL,"environment space does not exist"); + } + + return entry->global_pointer; + } + + MemoryContext GetTopMemoryContext(void) + { + PGEnv env = GetEnv(); + if ( env == NULL ) return NULL; + return env->GlobalContext; + } *** 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 Wed Feb 27 01:03:07 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); /* *************** *** 78,90 **** * rate --- we don't really expect much to be allocated in it. * * (There is special-case code in MemoryContextCreate() for this call.) ! */ TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL, "TopMemoryContext", 8 * 1024, 8 * 1024, 8 * 1024); ! /* * Not having any other place to point CurrentMemoryContext, make it * point to TopMemoryContext. Caller should change this soon! --- 84,101 ---- * rate --- we don't really expect much to be allocated in it. * * (There is special-case code in MemoryContextCreate() for this call.) ! * ! * ! * If the global environment is being used, the top memory context is ! * already created in the global environment. ! */ ! #ifndef USE_GLOBAL_ENVIRONMENT TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL, "TopMemoryContext", 8 * 1024, 8 * 1024, 8 * 1024); ! #endif /* * Not having any other place to point CurrentMemoryContext, make it * point to TopMemoryContext. Caller should change this soon! *************** *** 105,110 **** --- 116,147 ---- 8 * 1024, 8 * 1024); } + #ifdef USE_GLOBAL_ENVIRONMENT + void + MemoryContextDestroy(void) + { + MemoryContextDestroyEnv(); + } + + void + MemoryContextInitEnv(void) + { + AllocateEnvSpace(mem_section_id, + 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 Wed Feb 27 00:55:28 2002 *************** *** 0 **** --- 1,45 ---- + + /*------------------------------------------------------------------------- + * + * 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" + #include "nodes/memnodes.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); + + MemoryContext GetTopMemoryContext(void); + + #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 Wed Feb 27 00:54:43 2002 *************** *** 17,22 **** --- 17,23 ---- #ifndef MEMUTILS_H #define MEMUTILS_H + #include "env/env.h" #include "nodes/memnodes.h" *************** *** 64,69 **** --- 65,71 ---- * 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); --- 73,97 ---- extern DLLIMPORT MemoryContext QueryContext; extern DLLIMPORT MemoryContext TopTransactionContext; extern DLLIMPORT MemoryContext TransactionCommandContext; ! #else ! #define TopMemoryContext GetTopMemoryContext() ! #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 MemoryContextDestroy(void); + 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 Wed Feb 27 00:35:01 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,74 ---- * 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 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);