Example #1
0
/* PROGRAM: dsmRLwriter - Recovery log block writer thread
 *
 *
 * RETURNS: DSM_S_SUCCESS
 */
dsmStatus_t DLLEXPORT
dsmRLwriter(
        dsmContext_t *pcontext)
{
    dsmStatus_t  returnCode = 0;

#if OPSYS==WIN32API
    if (fWin95)
        return -1;
#endif

    SETJMP_ERROREXIT(pcontext, returnCode) /* Ensure error exit address set */

    if ((returnCode = dsmThreadSafeEntry(pcontext)) != DSM_S_SUCCESS)
    {
        returnCode = dsmEntryProcessError(pcontext, returnCode,
                      (TEXT *)"dsmRLwriter");
        goto done;
    }
    pcontext->pusrctl->uc_usrtyp = BIW;

    pcontext->pdbcontext->prlctl->abiwpid = pcontext->pusrctl->uc_pid;
    pcontext->pdbcontext->prlctl->qbiwq = QSELF(pcontext->pusrctl);
    
    rlbiclean(pcontext);
    if(pcontext->pdbcontext->pdbpub->shutdn)
        returnCode = DSM_S_SHUT_DOWN;
done:
    dsmThreadSafeExit(pcontext);

    return returnCode;
}
Example #2
0
/* PROGRAM: dbXAinit - Initialize the global xid free list
 *
 *
 * RETURNS: DSM_S_SUCCESS on success
 */
dsmStatus_t
dbxaInit(dsmContext_t *pcontext)
{
    dbcontext_t  *pdbcontext = pcontext->pdbcontext;
    dbshm_t      *pdbshm = pdbcontext->pdbpub;
    LONG          maxxids,amount;
    int           i;
    dbxaTransaction_t *pxids, *plastxid = NULL;
    
    if (!pdbshm->maxxids)
        return 0;

   
    amount = pdbshm->maxxids;
    for(pdbshm->maxxids = 0; pdbshm->maxxids < amount;
        pdbshm->maxxids += 64 )
    {
        /* Allocate the xids in chunks of 64         */
        pxids = (dbxaTransaction_t *)
            stGet(pcontext,
                  XSTPOOL(pdbcontext, pdbshm->qdbpool),
                  64 * sizeof(dbxaTransaction_t));
        if(!pxids)
        {
            MSGD_CALLBACK(pcontext,
                          "%gInsuffient storage to allocate xid table.");
        }
        if(plastxid)
        {
            /* Make last of previous batch of 64 point to this batch */
            plastxid->qnextXID = P_TO_QP(pcontext,pxids);
        }
        if(!pdbshm->qxidFree)
        {
            pdbshm->qxidFree = P_TO_QP(pcontext,pxids);
        }
        
        for(i = 0; i < 64;i++,pxids++)
        {
            QSELF(pxids) = P_TO_QP(pcontext,pxids);
            pxids->qnextXID = P_TO_QP(pcontext,pxids + 1);
        }
        plastxid = pxids--;
        plastxid->qnextXID = 0;
    }
    
    return 0;
}
Example #3
0
/* PROGRAM: dbxaFree - Return the specified global transaction structure
                       to the free list.

   RETURNS: nothing
*/
DSMVOID
dbxaFree(dsmContext_t  *pcontext, dbxaTransaction_t *ptran)
{
    dbshm_t   *pdbshm = pcontext->pdbcontext->pdbpub;
    
    ptran->flags = 0;
    ptran->trid = 0;
    ptran->referenceCount = 0;
    ptran->numSuspended = 0;
    ptran->lastRLblock = 0;
    ptran->lastRLoffset = 0;
    pdbshm->qxidAlloc = ptran->qnextXID;
    ptran->qnextXID = pdbshm->qxidFree;
    pdbshm->qxidFree = QSELF(ptran);

    return;
}
Example #4
0
/* PROGRAM: dbxaAllocate - Allocate a global transaction structure from
                           the free list.  Assumes the caller has locked
                           the list before calling.

   RETURNS: pointer to global tx structure
 */
dbxaTransaction_t *dbxaAllocate(dsmContext_t *pcontext)
{
    dbxaTransaction_t  *pxaTran;
    dbcontext_t        *pdbcontext = pcontext->pdbcontext;
    dbshm_t            *pdbshm = pdbcontext->pdbpub;
    
    pxaTran = XXID(pdbcontext,pdbshm->qxidFree);
    if(pxaTran)
    {
        pdbshm->qxidFree = pxaTran->qnextXID;
        pxaTran->qnextXID = pdbshm->qxidAlloc;
        pdbshm->qxidAlloc = QSELF(pxaTran);
    }
    else
    {
        /* If the free list is empty we should wait for one to become free */
        ;
    }
    return pxaTran;
}
Example #5
0
/* PROGRAM: rlaiseto - initialize aictl and buffers
*/
DSMVOID
rlaiseto (dsmContext_t *pcontext)
{
    dbcontext_t     *pdbcontext = pcontext->pdbcontext;
    dbshm_t     *pdbpub = pdbcontext->pdbpub;
    AICTL	*paictl;
    BKTBL	*pbktbl;
    AIBUF	*paibuf = (AIBUF *)0;
    AIBUF	*pn;
    int	i;

    /* *** TODO: there is a memory leak when peforming aimage begin on a
     * database that has 2phase on already rlaiseto is called twice.  Not
     * a big deal, but something to remember.
     */
    if (pdbcontext->paictl != NULL)
    {
	/* memory leak! */
    }

    /* allocate the ai control structure */
    paictl = (AICTL *)stGet(pcontext, (STPOOL *)QP_TO_P(pdbcontext, pdbpub->qdbpool),
                                              sizeof(AICTL));
    pdbpub->qaictl = P_TO_QP(pcontext, paictl);
    pdbcontext->paictl = paictl;

    /* initialize blocksize information based on masterblock info */
    paictl->aiblksize = pdbcontext->pmstrblk->mb_aiblksize;
    paictl->aiFileType = BKAI;

    /* initialize block size log and mask constants for quick calculations */
    paictl->aiblklog = bkblklog(paictl->aiblksize);
    paictl->aiblkmask = (ULONG)0xFFFFFFFF << paictl->aiblklog;

    /* 
     * allocate buffer for ai writer to use for writing. This buffer is
     * used for making a copy of the current buffer prior to writing
     * it so that the ai writer can be writing while others are storing
     * more data in the next output buffer.  Also used during extent switches.
     */

    pbktbl = &paictl->aiwbktbl;
    QSELF (pbktbl) = P_TO_QP(pcontext, pbktbl);

    pbktbl->bt_raddr = -1;
    pbktbl->bt_dbkey = -1;
    /* BUM - Assuming aiFileType < 256 */
    pbktbl->bt_ftype = (TEXT)paictl->aiFileType;
    if ( paictl->aiFileType == BKAI )
    {
       paictl->aiArea = rlaiGetNextArea(pcontext, 1);
       if( pdbcontext->pmstrblk->mb_aibusy_extent )
       {
	  paictl->aiArea = pdbcontext->pmstrblk->mb_aibusy_extent;
       }
    }
    else
    {
    	paictl->aiArea = DSMAREA_TL;
    }
    pbktbl->bt_area = paictl->aiArea;
    
    bmGetBufferPool(pcontext, pbktbl);

    /* must have at least one ai buffer */
    if (pdbpub->argaibufs < 1) pdbpub->argaibufs = 1;

    /* allocate a ring of output ai buffer control blocks */
    pn = NULL;
    for (i = pdbpub->argaibufs; i > 0; i--)
    {
        paibuf = (AIBUF *)stGet (pcontext, (STPOOL *)QP_TO_P(pdbcontext, pdbpub->qdbpool),
			 	 sizeof(AIBUF));
        QSELF (paibuf) = P_TO_QP(pcontext, paibuf);

	if (pn)
	{
	    /* set previous buffer's link to next buffer in chain */
	    pn->aiqnxtb = QSELF (paibuf);
	}
	else
	{
	    /* this is the first, current, and next to write buffer */
	    paictl->aiqbufs = QSELF (paibuf);
            paictl->aiqcurb = QSELF (paibuf);
            paictl->aiqwrtb = QSELF (paibuf);
	}
	pn = paibuf;
    }

    /* link the last one to the first one */
    paibuf->aiqnxtb = paictl->aiqbufs;

    /* now allocate the ai block buffers themselves */
    pn = XAIBUF(pdbcontext, paictl->aiqbufs);
    for (i = pdbpub->argaibufs; i > 0; i--)
    {
	pbktbl = &(pn->aibk);

        QSELF (pbktbl) = P_TO_QP(pcontext, pbktbl);

        pbktbl->bt_raddr = -1;
	pbktbl->bt_dbkey = -1;
        pbktbl->bt_area = paictl->aiArea;
        /* BUM - Assuming UCOUNT aiFileType < 256 */
        pbktbl->bt_ftype = (TEXT)paictl->aiFileType;
        bmGetBufferPool(pcontext, pbktbl);
	pn = XAIBUF(pdbcontext, pn->aiqnxtb);
    }

} /* rlaiseto */