summaryrefslogtreecommitdiff
path: root/lib/libc/db/mpool/mpool.libtp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/db/mpool/mpool.libtp')
-rw-r--r--lib/libc/db/mpool/mpool.libtp746
1 files changed, 0 insertions, 746 deletions
diff --git a/lib/libc/db/mpool/mpool.libtp b/lib/libc/db/mpool/mpool.libtp
deleted file mode 100644
index 160f7369a8a..00000000000
--- a/lib/libc/db/mpool/mpool.libtp
+++ /dev/null
@@ -1,746 +0,0 @@
-/******************************************************************************
-
-VERSION $OpenBSD: mpool.libtp,v 1.3 1999/02/15 05:11:25 millert Exp $
-PACKAGE: User Level Shared Memory Manager
-
-DESCRIPTION:
- This package provides a buffer pool interface implemented as
- a collection of file pages mapped into shared memory.
-
- Based on Mark's buffer manager
-
-ROUTINES:
- External
- buf_alloc
- buf_flags
- buf_get
- buf_init
- buf_last
- buf_open
- buf_pin
- buf_sync
- buf_unpin
- Internal
- bf_assign_buf
- bf_fid_to_fd
- bf_newbuf
- bf_put_page
-
-
-******************************************************************************/
-#include <sys/types.h>
-#include <assert.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <errno.h>
-#include "list.h"
-#include "user.h"
-#include "txn_sys.h"
-#include "buf.h"
-#include "semkeys.h"
-#include "error.h"
-
-/*
- we need to translate between some type of file id that the user
- process passes and a file descriptor. For now, it's a nop.
-*/
-#define GET_MASTER get_sem ( buf_spinlock )
-#define RELEASE_MASTER release_sem ( buf_spinlock )
-
-#define LRUID *buf_lru
-#define LRUP (bufhdr_table+*buf_lru)
-#define MRU bufhdr_table[*buf_lru].lru.prev
-
-/* Global indicator that you have started reusing buffers */
-int do_statistics = 0;
-/*
- Process Statics (pointers into shared memory)
-*/
-static BUF_T *buf_table = 0;
-static BUFHDR_T *bufhdr_table;
-static int *buf_hash_table;
-static int *buf_lru; /* LRU is the free list */
-static int buf_spinlock;
-static FINFO_T *buf_fids;
-static int *buf_sp; /* Pointer to string free space */
-static char *buf_strings;
-
-/* Process Local FID->FD table */
-static int fds[NUM_FILE_ENTRIES];
-
-/* Static routines */
-static BUFHDR_T *bf_assign_buf();
-static int bf_fid_to_fd();
-static BUFHDR_T *bf_newbuf();
-static int bf_put_page();
-
-/*
- Return 0 on success
- 1 on failure
-*/
-extern int
-buf_init ( )
-{
- ADDR_T buf_region;
- BUFHDR_T *bhp;
- int i;
- int ref_count;
- int *spinlockp;
-
- /*
- Initialize Process local structures
- */
- for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
- fds[i] = -1;
- }
-
- buf_region = attach_region ( BUF_REGION_NAME, BUF_REGION_NUM,
- BUF_REGION_SIZE, &ref_count );
- if ( !buf_region ) {
- return (1);
- }
- error_log3 ( "Buf Region: ADDR: %d ID: %d SIZE: %d\n", buf_region,
- BUF_REGION_NUM, BUF_REGION_SIZE );
-
- buf_table = (BUF_T *)buf_region;
- bufhdr_table = (BUFHDR_T *)(buf_table + NUM_BUFS);
- buf_hash_table = (int *)(bufhdr_table + NUM_BUFS);
- buf_lru = buf_hash_table + NUMTABLE_ENTRIES;
- spinlockp = buf_lru + 1;
- buf_fids = (FINFO_T *)(spinlockp+1);
- buf_sp = (int *)(buf_fids + NUM_FILE_ENTRIES);
- buf_strings = (char *)(buf_sp + 1);
-
- /* Create locking spinlock (gets creating holding the lock) */
- buf_spinlock = create_sem ( BUF_SPIN_NAME, BUF_SPIN_NUM, ref_count <= 1 );
- if ( buf_spinlock < 0 ) {
- return(1);
- }
- if ( ref_count <= 1 ) {
- *spinlockp = buf_spinlock;
-
- /* Now initialize the buffer manager */
-
- /* 1. Free list */
- *buf_lru = 0;
-
- /* 2. Buffer headers */
- for ( i = 0, bhp = bufhdr_table; i < NUM_BUFS; bhp++, i++ ) {
- bhp->lru.next = i+1;
- bhp->lru.prev = i-1;
- bhp->flags = 0; /* All Flags off */
- bhp->refcount = 0;
- bhp->wait_proc = -1; /* No sleepers */
- LISTPE_INIT ( hash, bhp, i ); /* Hash chains */
- }
- bufhdr_table[0].lru.prev = NUM_BUFS-1;
- bufhdr_table[NUM_BUFS-1].lru.next = 0;
-
- /* 3. Hash Table */
- for ( i = 0; i < NUMTABLE_ENTRIES; i++ ) {
- buf_hash_table[i] = NUM_BUFS;
- }
-
- /* 4. File ID Table */
- for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
- buf_fids[i].offset = -1;
- buf_fids[i].npages = -1;
- buf_fids[i].refcount = 0;
- }
-
- /* 5. Free String Pointer */
- *buf_sp = (FILE_NAME_LEN*NUM_FILE_ENTRIES);
- if (RELEASE_MASTER) {
- return(1);
- }
- error_log0 ( "Initialized buffer region\n" );
- }
- return (0);
-}
-
-extern void
-buf_exit()
-{
- int ref;
- int i;
-
- /* Flush Buffer Pool on Exit */
- for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
- if ( fds[i] != -1 ) {
- close ( fds[i] );
- }
- }
- if ( buf_table ) {
- detach_region ( buf_table, BUF_REGION_NUM, BUF_REGION_SIZE, &ref );
- }
- return;
-}
-
-/*
- We need an empty buffer. Find the LRU unpinned NON-Dirty page.
-*/
-static BUFHDR_T *
-bf_newbuf()
-{
- int fd;
- int lruid;
- int nbytes;
- int ndx;
- BUFHDR_T *bhp;
-
- lruid = LRUID;
- for ( bhp = LRUP;
- bhp->flags & (BUF_PINNED|BUF_IO_IN_PROGRESS);
- bhp = LISTP_NEXTP (bufhdr_table, lru, bhp ) ) {
-
- if ( bhp->lru.next == lruid ) {
- /* OUT OF BUFFERS */
- error_log1 ( "All buffers are pinned. %s\n",
- "Unable to grant buffer request" );
- return(NULL);
- }
- }
- /* BHP can be used */
- if ( bhp->flags & BUF_DIRTY ) {
- do_statistics = 1;
- /*
- MIS Check for log flushed appropriately
- */
- fd = bf_fid_to_fd(bhp->id.file_id);
- if ( fd == -1 ) {
- error_log1 ("Invalid fid %d\n", bhp->id.file_id);
- return(NULL);
- }
- if ( bf_put_page(fd, bhp) < 0 ) {
- return(NULL);
- }
- }
- /* Update Hash Pointers */
- ndx = BUF_HASH ( bhp->id.file_id, bhp->id.obj_id );
- LISTP_REMOVE(bufhdr_table, hash, bhp);
- if ( buf_hash_table[ndx] == (bhp-bufhdr_table) ) {
- if ( bhp->hash.next != (bhp-bufhdr_table) ) {
- buf_hash_table[ndx] = bhp->hash.next;
- } else {
- buf_hash_table[ndx] = NUM_BUFS;
- }
- }
- INIT_BUF(bhp);
-
- return(bhp);
-}
-/*
- buf_alloc
-
- Add a page to a file and return a buffer for it.
-
-*/
-ADDR_T
-buf_alloc ( fid, new_pageno )
-int fid;
-int *new_pageno;
-{
- BUFHDR_T *bhp;
- int fd;
- int len;
- int ndx;
- OBJ_T fobj;
-
- if (GET_MASTER) {
- return(NULL);
- }
- if ( buf_fids[fid].npages == -1 ) {
- /* initialize npages field */
- fd = bf_fid_to_fd ( fid );
- }
- assert (fid < NUM_FILE_ENTRIES);
-
- *new_pageno = buf_fids[fid].npages;
- if ( *new_pageno == -1 ) {
- RELEASE_MASTER;
- return ( NULL );
- }
- buf_fids[fid].npages++;
- ndx = BUF_HASH ( fid, *new_pageno );
- fobj.file_id = fid;
- fobj.obj_id = *new_pageno;
- bhp = bf_assign_buf ( ndx, &fobj, BF_PIN|BF_DIRTY|BF_EMPTY, &len );
- if ( RELEASE_MASTER ) {
- /* Memory leak */
- return(NULL);
- }
- if ( bhp ) {
- return ((ADDR_T)(buf_table+(bhp-bufhdr_table)));
- } else {
- return ( NULL );
- }
-}
-
-
-/*
- Buffer Flags
- BF_DIRTY Mark page as dirty
- BF_EMPTY Don't initialize page, just get buffer
- BF_PIN Retrieve with pin
-
-MIS
-Might want to add a flag that sets an LSN for this buffer is the
-DIRTY flag is set
-
-Eventually, you may want a flag that indicates the I/O and lock
-request should be shipped off together, but not for now.
-*/
-extern ADDR_T
-buf_get ( file_id, page_id, flags, len )
-int file_id;
-int page_id;
-u_long flags;
-int *len; /* Number of bytes read into buffer */
-{
- BUFHDR_T *bhp;
- int bufid;
- int fd;
- int ndx;
- int next_bufid;
- int stat;
- OBJ_T fobj;
-
- ndx = BUF_HASH ( file_id, page_id );
- fobj.file_id = (long) file_id;
- fobj.obj_id = (long) page_id;
- if ( GET_MASTER ) {
- return(NULL);
- }
- /*
- This could be a for loop, but we lose speed
- by making all the cases general purpose so we
- optimize for the no-collision case.
- */
- bufid = buf_hash_table[ndx];
- if ( bufid < NUM_BUFS ) {
- for ( bhp = bufhdr_table+bufid;
- !OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID);
- bhp = LISTP_NEXTP ( bufhdr_table, hash, bhp ) ) {
-
- if ( bhp->hash.next == bufid ) {
- goto not_found;
- }
- }
-/* found */
- if ( flags & BF_PIN ) {
- bhp->flags |= BUF_PINNED;
- bhp->refcount++;
-#ifdef PIN_DEBUG
- fprintf(stderr, "buf_get: %X PINNED (%d)\n",
- buf_table + (bhp-bufhdr_table), bhp->refcount);
-#endif
- }
- if ( flags & BF_DIRTY ) {
- bhp->flags |= BUF_DIRTY;
- }
-
- while ( bhp->flags & BUF_IO_IN_PROGRESS ) {
- /* MIS -- eventually err check here */
-#ifdef DEBUG
- printf("About to sleep on %d (me: %d\n)\n", bhp->wait_proc,
- my_txnp - txn_table);
-#endif
-#ifdef WAIT_STATS
- buf_waits++;
-#endif
- stat = proc_sleep_on ( &(bhp->wait_proc), buf_spinlock );
- if ( stat ) {
- /* Memory leak */
- return(NULL);
- }
- if (!( bhp->flags & BUF_IO_IN_PROGRESS) &&
- (!OBJ_EQ (bhp->id, fobj) || !(bhp->flags & BUF_VALID))) {
- if (RELEASE_MASTER)
- return(NULL);
- return(buf_get ( file_id, page_id, flags, len ));
- }
- }
- MAKE_MRU( bhp );
- *len = BUFSIZE;
- } else {
-not_found:
- /* If you get here, the page isn't in the hash table */
- bhp = bf_assign_buf ( ndx, &fobj, flags, len );
- }
- /* Common code between found and not found */
-
- if ( bhp && bhp->flags & BUF_NEWPAGE ) {
- *len = 0;
- }
- if (RELEASE_MASTER){
- /* Memory leak */
- return(NULL);
- }
- if ( bhp ) {
- return ((ADDR_T)(buf_table+(bhp-bufhdr_table)));
- } else {
- return ( NULL );
- }
-}
-
-/*
- MIS - do I want to add file links to buffer pool?
-*/
-extern int
-buf_sync ( fid, close )
-int fid;
-int close; /* should we dec refcount and possibly
- invalidate all the buffers */
-{
- int i;
- int fd;
- int invalidate;
- BUFHDR_T *bhp;
-
- if ( (fd = bf_fid_to_fd ( fid )) < 0 ) {
- return(1);
- }
- if (GET_MASTER) {
- return(1);
- }
- invalidate = (buf_fids[fid].refcount == 1 && close);
- if ( invalidate )
- for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) {
- if (bhp->id.file_id == fid) {
- if ((bhp->flags & BF_DIRTY) && (bf_put_page( fd, bhp ) < 0)) {
- return(1);
- }
- bhp->id.file_id = -1;
- }
- }
- if (invalidate || close)
- buf_fids[fid].refcount--;
-
- if (RELEASE_MASTER) {
- return(1);
- }
- return(0);
-
-
-}
-
-extern int
-buf_flags ( addr, set_flags, unset_flags )
-ADDR_T addr;
-u_long set_flags;
-u_long unset_flags;
-{
- int bufid;
- BUFHDR_T *bhp;
-
-#ifdef PIN_DEBUG
- fprintf(stderr, "buf_flags: %X setting %s%s%s%s%s releasing %s%s%s%s%s\n",
- addr,
- set_flags&BUF_DIRTY ? "DIRTY " : "",
- set_flags&BUF_VALID ? "VALID " : "",
- set_flags&BUF_PINNED ? "PINNED " : "",
- set_flags&BUF_IO_ERROR ? "IO_ERROR " : "",
- set_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "",
- set_flags&BUF_NEWPAGE ? "NEWPAGE " : "",
- unset_flags&BUF_DIRTY ? "DIRTY " : "",
- unset_flags&BUF_VALID ? "VALID " : "",
- unset_flags&BUF_PINNED ? "PINNED " : "",
- unset_flags&BUF_IO_ERROR ? "IO_ERROR " : "",
- unset_flags&BUF_IO_IN_PROGRESS ? "IO_IN_PROG " : "",
- unset_flags&BUF_NEWPAGE ? "NEWPAGE " : "" );
-#endif
- if (!ADDR_OK(addr)) {
- error_log1 ( "buf_pin: Invalid Buffer Address %x\n", addr );
- return(1);
- }
- bufid = ((BUF_T *)addr) - buf_table;
- assert ( bufid < NUM_BUFS);
- bhp = &bufhdr_table[bufid];
- if (GET_MASTER) {
- return(1);
- }
- bhp->flags |= set_flags;
- if ( set_flags & BUF_PINNED ) {
- bhp->refcount++;
- }
- if ( set_flags & BUF_DIRTY ) {
- unset_flags |= BUF_NEWPAGE;
- }
-
- if ( unset_flags & BUF_PINNED ) {
- bhp->refcount--;
- if ( bhp->refcount ) {
- /* Turn off pin bit so it doesn't get unset */
- unset_flags &= ~BUF_PINNED;
- }
- }
- bhp->flags &= ~unset_flags;
- MAKE_MRU(bhp);
- if (RELEASE_MASTER) {
- return(1);
- }
- return(0);
-}
-
-/*
- Take a string name and produce an fid.
-
- returns -1 on error
-
- MIS -- this is a potential problem -- you keep actual names
- here -- what if people run from different directories?
-*/
-extern int
-buf_name_lookup ( fname )
-char *fname;
-{
- int i;
- int fid;
- int ndx;
-
- fid = -1;
- if (GET_MASTER) {
- return(-1);
- }
- for ( i = 0; i < NUM_FILE_ENTRIES; i++ ) {
- if ( buf_fids[i].offset == -1 ) {
- fid = i;
- } else {
- if (!strcmp (fname, buf_strings+buf_fids[i].offset)) {
- if (RELEASE_MASTER) {
- return(-1);
- }
- buf_fids[i].refcount++;
- return(i);
- }
- }
- }
- if ( fid == -1 ) {
- error_log0 ( "No more file ID's\n" );
- } else {
- ndx = *buf_sp - strlen(fname) - 1;
- if ( ndx < 0 ) {
- error_log0 ( "Out of string space\n" );
- fid = -1;
- } else {
- *buf_sp = ndx;
- strcpy ( buf_strings+ndx, fname );
- buf_fids[fid].offset = ndx;
- }
- buf_fids[fid].refcount = 1;
- }
- if (RELEASE_MASTER) {
- return(-1);
- }
- return(fid);
-}
-
-static int
-bf_fid_to_fd ( fid )
-int fid;
-{
- struct stat sbuf;
-
- assert ( (fid < NUM_FILE_ENTRIES) && (buf_fids[fid].offset != -1) );
- if ( fds[fid] != -1 ) {
- return(fds[fid]);
-
- }
- fds[fid] = open ( buf_strings+buf_fids[fid].offset, O_RDWR|O_CREAT,
- 0666 );
- if ( fds[fid] < 0 ) {
- error_log3 ( "Error Opening File %s FID: %d FD: %d. Errno = %d\n",
- buf_strings+buf_fids[fid].offset, fid, fds[fid],
- errno );
- return(-1);
- }
- error_log3 ( "Opening File %s FID: %d FD: %d\n",
- buf_strings+buf_fids[fid].offset, fid, fds[fid] );
- if ( buf_fids[fid].npages == -1 ) {
- /* Initialize the npages field */
- if ( fstat ( fds[fid], &sbuf ) ) {
- error_log3 ( "Error Fstating %s FID: %d. Errno = %d\n",
- buf_strings+buf_fids[fid].offset, fid, errno );
- } else {
- buf_fids[fid].npages = ( sbuf.st_size / BUFSIZE );
- }
- }
-
- return ( fds[fid] );
-}
-
-static int
-bf_put_page ( fd, bhp )
-int fd;
-BUFHDR_T *bhp;
-{
- int nbytes;
-
- assert ( (bhp-bufhdr_table) < NUM_BUFS );
- if ( lseek ( fd, bhp->id.obj_id << BUFSHIFT, SEEK_SET ) < 0 ) {
- return(-1);
- }
- bhp->flags |= BUF_IO_IN_PROGRESS;
- if (RELEASE_MASTER) {
- return(-1);
- }
- nbytes = write(fd, buf_table[bhp-bufhdr_table], BUFSIZE);
- if (GET_MASTER) {
- return(-2);
- }
- if ( nbytes < 0 ) {
- error_log1 ("Write failed with error code %d\n", errno);
- return(-1);
- } else if ( nbytes != BUFSIZE ) {
- error_log1 ("Short write: %d bytes of %d\n", nbytes, BUFSIZE );
- }
- bhp->flags &= ~(BUF_DIRTY|BUF_IO_IN_PROGRESS);
- return (0);
-}
-
-static BUFHDR_T *
-bf_assign_buf ( ndx, obj, flags, len )
-int ndx;
-OBJ_T *obj;
-u_long flags;
-int *len; /* Number of bytes read */
-{
- BUFHDR_T *bhp;
- int fd;
-
- assert ( obj->file_id < NUM_FILE_ENTRIES );
- bhp = bf_newbuf();
- if ( !bhp ) {
- return(NULL);
- }
- OBJ_ASSIGN ( (*obj), bhp->id );
- if ( buf_hash_table[ndx] >= NUM_BUFS ) {
- buf_hash_table[ndx] = bhp-bufhdr_table;
- } else {
- LISTPE_INSERT ( bufhdr_table, hash, bhp, buf_hash_table[ndx] );
- }
-
- bhp->flags |= BUF_VALID;
- if ( flags & BF_PIN ) {
- bhp->flags |= BUF_PINNED;
- bhp->refcount++;
-#ifdef PIN_DEBUG
- fprintf(stderr, "bf_assign_buf: %X PINNED (%d)\n",
- buf_table + (bhp-bufhdr_table), bhp->refcount);
-#endif
- }
- fd = bf_fid_to_fd(obj->file_id);
- if ( fd == -1 ) {
- error_log1 ("Invalid fid %d\n", obj->file_id);
- bhp->flags |= ~BUF_IO_ERROR;
- return(NULL);
- }
- if ( obj->obj_id >= buf_fids[obj->file_id].npages) {
- buf_fids[obj->file_id].npages = obj->obj_id+1;
- *len = 0;
- } else if ( flags & BF_EMPTY ) {
- *len = 0;
- } else {
- bhp->flags |= BUF_IO_IN_PROGRESS;
- if (RELEASE_MASTER) {
- return(NULL);
- }
- if ( lseek ( fd, obj->obj_id << BUFSHIFT, SEEK_SET ) < -1 ) {
- error_log2 ("Unable to perform seek on file: %d to page %d",
- obj->file_id, obj->obj_id );
- bhp->flags &= ~BUF_IO_IN_PROGRESS;
- bhp->flags |= ~BUF_IO_ERROR;
- return(NULL);
- }
- *len = read(fd, buf_table[bhp-bufhdr_table], BUFSIZE);
- if ( *len < 0 ) {
- error_log2 ("Unable to perform read on file: %d to page %d",
- obj->file_id, obj->obj_id );
- bhp->flags &= ~BUF_IO_IN_PROGRESS;
- bhp->flags |= ~BUF_IO_ERROR;
- return(NULL);
- }
- if (GET_MASTER) {
- return(NULL);
- }
- bhp->flags &= ~BUF_IO_IN_PROGRESS;
- if ( bhp->wait_proc != -1 ) {
- /* wake up waiter and anyone waiting on it */
-#ifdef DEBUG
- printf("Waking transaction %d due to completed I/O\n",
- bhp->wait_proc);
-#endif
- proc_wake_id ( bhp->wait_proc );
- bhp->wait_proc = -1;
- }
- MAKE_MRU(bhp);
- }
-
- if ( flags & BF_DIRTY ) {
- bhp->flags |= BUF_DIRTY;
- } else if ( *len < BUFSIZE ) {
- bhp->flags |= BUF_NEWPAGE;
- }
- return ( bhp );
-}
-
-int
-buf_last ( fid )
-int fid;
-{
- int val;
-
- if (GET_MASTER) {
- return(-1);
- }
- assert ( fid < NUM_FILE_ENTRIES );
- if ( buf_fids[fid].npages == -1 ) {
- /* initialize npages field */
- (void) bf_fid_to_fd ( fid );
- }
- val = buf_fids[fid].npages;
- if ( val ) {
- val--; /* Convert to page number */
- }
- if (RELEASE_MASTER) {
- return(-1);
- }
- return(val);
-}
-
-#ifdef DEBUG
-extern void
-buf_dump ( id, all )
-int id;
-int all;
-{
- int i;
- BUFHDR_T *bhp;
-
- printf ( "LRU + %d\n", *buf_lru );
- if ( all ) {
- printf("ID\tFID\tPID\tLNEXT\tLPREV\tHNEXT\tHPREV\tSLEEP\tFLAG\tREFS\n");
- for ( bhp = bufhdr_table, i = 0; i < NUM_BUFS; bhp++, i++ ) {
- printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i,
- bhp->id.file_id, bhp->id.obj_id,
- bhp->lru.next, bhp->lru.prev,
- bhp->hash.next, bhp->hash.prev,
- bhp->wait_proc, bhp->flags, bhp->refcount );
- }
- } else {
- if ( id >= NUM_BUFS ) {
- printf ( "Buffer ID (%d) too high\n", id );
- return;
- }
- bhp = bufhdr_table+id;
- printf ( "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%x\t%d\n", i,
- bhp->id.file_id, bhp->id.obj_id,
- bhp->lru.next, bhp->lru.prev,
- bhp->hash.next, bhp->hash.prev,
- bhp->wait_proc, bhp->flags, bhp->refcount );
- }
- return;
-}
-#endif
-