Exemplo n.º 1
0
void cm_InitCell(int newFile, long maxCells)
{
    static osi_once_t once;

    if (osi_Once(&once)) {
        cm_cell_t * cellp;

        lock_InitializeRWLock(&cm_cellLock, "cell global lock", LOCK_HIERARCHY_CELL_GLOBAL);

        if ( newFile ) {
            cm_data.allCellsp = NULL;
            cm_data.currentCells = 0;
            cm_data.maxCells = maxCells;
            memset(cm_data.cellNameHashTablep, 0, sizeof(cm_cell_t *) * cm_data.cellHashTableSize);
            memset(cm_data.cellIDHashTablep, 0, sizeof(cm_cell_t *) * cm_data.cellHashTableSize);

#ifdef AFS_FREELANCE_CLIENT
            /* Generate a dummy entry for the Freelance cell whether or not
             * freelance mode is being used in this session
             */

            cellp = &cm_data.cellBaseAddress[cm_data.currentCells++];
            memset(cellp, 0, sizeof(cm_cell_t));
            cellp->magic = CM_CELL_MAGIC;

            lock_InitializeMutex(&cellp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);

            lock_ObtainMutex(&cellp->mx);
            lock_ObtainWrite(&cm_cellLock);

            /* copy in name */
            strncpy(cellp->name, "Freelance.Local.Cell", CELL_MAXNAMELEN); /*safe*/
            cellp->name[CELL_MAXNAMELEN-1] = '\0';

            /* thread on global list */
            cellp->allNextp = cm_data.allCellsp;
            cm_data.allCellsp = cellp;

            cellp->cellID = AFS_FAKE_ROOT_CELL_ID;
            cellp->vlServersp = NULL;
            _InterlockedOr(&cellp->flags, CM_CELLFLAG_FREELANCE);

            cm_AddCellToNameHashTable(cellp);
            cm_AddCellToIDHashTable(cellp);
            lock_ReleaseWrite(&cm_cellLock);
            lock_ReleaseMutex(&cellp->mx);
#endif
        } else {
            lock_ObtainRead(&cm_cellLock);
            for (cellp = cm_data.allCellsp; cellp; cellp=cellp->allNextp) {
                lock_InitializeMutex(&cellp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);
                cellp->vlServersp = NULL;
                _InterlockedOr(&cellp->flags, CM_CELLFLAG_VLSERVER_INVALID);
            }
            lock_ReleaseRead(&cm_cellLock);
        }

        osi_EndOnce(&once);
    }
}
Exemplo n.º 2
0
/* must be called with sleep bucket locked.
 * Frees the structure if it has a 0 reference count (and removes it
 * from the hash bucket).  Otherwise, we simply mark the item
 * for deleting when the ref count hits zero.
 */
void osi_FreeSleepInfo(osi_sleepInfo_t *sp)
{
    LONG_PTR idx;

    if (sp->refCount > 0) {
	TlsSetValue(osi_SleepSlot, NULL);	/* don't reuse me */
	_InterlockedOr(&sp->states, OSI_SLEEPINFO_DELETED);
	return;
    }

    /* remove from hash if still there */
    if (sp->states & OSI_SLEEPINFO_INHASH) {
	idx = osi_SLEEPHASH(sp->value);
	osi_QRemoveHT((osi_queue_t **) &osi_sleepers[idx], (osi_queue_t **) &osi_sleepersEnd[idx], &sp->q);
	_InterlockedAnd(&sp->states, ~OSI_SLEEPINFO_INHASH);
    }

    if (sp->states & OSI_SLEEPINFO_DELETED) {
	EnterCriticalSection(&osi_sleepInfoAllocCS);
	sp->q.nextp = (osi_queue_t *) osi_sleepInfoFreeListp;
	osi_sleepInfoFreeListp = sp;
	_InterlockedAnd(&sp->states, ~OSI_SLEEPINFO_DELETED);
	InterlockedIncrement(&osi_sleepInfoCount);
	LeaveCriticalSection(&osi_sleepInfoAllocCS);
    }
}
Exemplo n.º 3
0
/*----------------------------------------------------------------------------*/
VOID sdioINTerruptCallback(IN PVOID context, IN UINT_32 u4INTerruptType)
{
	P_GLUE_INFO_T prGlueInfo;
	PDEVICE_EXTENSION prDevExt;
	NTSTATUS rStatus;

	ASSERT(context);
	prGlueInfo = (P_GLUE_INFO_T) context;

	prDevExt = (PDEVICE_EXTENSION) &prGlueInfo->rHifInfo.dx;

	if (prGlueInfo->rHifInfo.u4ReqFlag & REQ_FLAG_HALT) {
		if (prDevExt->BusInterface.AcknowledgeInterrupt)
			rStatus = (prDevExt->BusInterface.AcknowledgeInterrupt) (prDevExt->BusInterface.Context);
		return;
	}

	wlanISR(prGlueInfo->prAdapter, TRUE);

	if (prDevExt->BusInterface.AcknowledgeInterrupt)
		rStatus = (prDevExt->BusInterface.AcknowledgeInterrupt) (prDevExt->BusInterface.Context);

	_InterlockedOr(&prGlueInfo->rHifInfo.u4ReqFlag, REQ_FLAG_INT);
/* KeSetEvent(&prGlueInfo->rHifInfo.rOidReqEvent, EVENT_INCREMENT, FALSE); */
	/* Set EVENT */
	NdisSetEvent(&prGlueInfo->rTxReqEvent);

	return;
}				/* end of sdioINTerruptCallback() */
Exemplo n.º 4
0
// This is meant to be called from the main thread only. 
void RequestSuspension() {
    if (!g_SuspensionRequested) {
        if (!ResetEvent(g_hResumeFromSuspension)) {
            exit(GetLastError());
        }
        _InterlockedOr(&g_SuspensionRequested, 1);
    }
}
Exemplo n.º 5
0
	/* _Atomic_load_4 */
static _Uint4_t _Load_seq_cst_4(volatile _Uint4_t *_Tgt)
	{	/* load from *_Tgt atomically with
			sequentially consistent memory order */
	_Uint4_t _Value;

	_Value = _InterlockedOr((volatile long *)_Tgt, 0);
	return (_Value);
	}
Exemplo n.º 6
0
/* like TSignal, only wake *everyone* */
void osi_TBroadcast(osi_turnstile_t *turnp)
{
    osi_sleepInfo_t *sp;

    while(sp = turnp->lastp) {
        osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
        _InterlockedOr(&sp->states, OSI_SLEEPINFO_SIGNALLED);
        ReleaseSemaphore(sp->sema, 1, NULL);
    }	/* while someone's still asleep */
}
Exemplo n.º 7
0
/* must be called with a critical section held that guards the turnstile
 * structure.  We remove the sleepInfo structure from the queue so we don't
 * wake the guy again, but we don't free it because we're still using the
 * semaphore until the guy waiting wakes up.
 */
void osi_TSignal(osi_turnstile_t *turnp)
{
    osi_sleepInfo_t *sp;

    if (!turnp->lastp)
        return;

    sp = turnp->lastp;
    osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &sp->q);
    _InterlockedOr(&sp->states, OSI_SLEEPINFO_SIGNALLED);
    ReleaseSemaphore(sp->sema, 1, NULL);
}
Exemplo n.º 8
0
unsigned
Atomic::OR(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
    return __sync_fetch_and_or(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
    return _InterlockedOr(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
    return OSAtomicOr32((uint32_t)value, (uint32_t *)&_value);
#else
# error This implementation should happen inline in the include file
#endif
}
Exemplo n.º 9
0
/* utility function to atomically (with respect to WakeSched)
 * release an atomic counter spin lock and sleep on an
 * address (value).
 * Called with no locks held.
 */
void osi_SleepSpin(LONG_PTR sleepValue, CRITICAL_SECTION *releasep)
{
    int code;
    osi_sleepInfo_t *sp;
    CRITICAL_SECTION *csp;

    sp = TlsGetValue(osi_SleepSlot);
    if (sp == NULL) {
	sp = osi_AllocSleepInfo();
	TlsSetValue(osi_SleepSlot, sp);
    }
    else {
	_InterlockedAnd(&sp->states, 0);
    }
    sp->waitFor = 0;
    sp->value = sleepValue;
    sp->tidp = NULL;
    sp->idx = osi_SLEEPHASH(sleepValue);
    csp = &osi_critSec[sp->idx];
    EnterCriticalSection(csp);
    osi_QAddT((osi_queue_t **) &osi_sleepers[sp->idx], (osi_queue_t **) &osi_sleepersEnd[sp->idx], &sp->q);
    _InterlockedOr(&sp->states, OSI_SLEEPINFO_INHASH);
    LeaveCriticalSection(csp);
    LeaveCriticalSection(releasep);
    InterlockedIncrement(&osi_totalSleeps);	/* stats */
    while(1) {
	/* wait */
	code = WaitForSingleObject(sp->sema,
				    /* timeout */ INFINITE);

	/* if the reason for the wakeup was that we were signalled,
	* break out, otherwise try again, since the semaphore count is
	* decreased only when we get WAIT_OBJECT_0 back.
	*/
	if (code == WAIT_OBJECT_0) break;
    }

    /* now clean up */
    EnterCriticalSection(csp);

    /* must be signalled */
    osi_assert(sp->states & OSI_SLEEPINFO_SIGNALLED);

    /* free the sleep structure, must be done under bucket lock
     * so that we can check reference count and serialize with
     * those who change it.
     */
    osi_FreeSleepInfo(sp);

    LeaveCriticalSection(csp);
}
void SL_AddUser(uint16_t string, int user)
{
	ScriptStringManagementData* data = slStrings[string].data;

	if (data)
	{
		SL_Debug("SL_AddUser: %i '%s' %i\n", string, slStrings[string].string, user);

		if (!(data->users & user))
		{
			SL_AddRefToString(string);
		}

		_InterlockedOr((long*)&data->users, user);
	}
}
Exemplo n.º 11
0
/* call with cell write-locked and mutex held */
void cm_AddCellToIDHashTable(cm_cell_t *cellp)
{
    int i;

    lock_AssertWrite(&cm_cellLock);
    lock_AssertMutex(&cellp->mx);

    if (cellp->flags & CM_CELLFLAG_IN_IDHASH)
        return;

    i = CM_CELL_ID_HASH(cellp->cellID);

    cellp->idNextp = cm_data.cellIDHashTablep[i];
    cm_data.cellIDHashTablep[i] = cellp;
    _InterlockedOr(&cellp->flags, CM_CELLFLAG_IN_IDHASH);
}
Exemplo n.º 12
0
/* call with volume write-locked and mutex held */
void cm_AddCellToNameHashTable(cm_cell_t *cellp)
{
    int i;

    lock_AssertWrite(&cm_cellLock);
    lock_AssertMutex(&cellp->mx);

    if (cellp->flags & CM_CELLFLAG_IN_NAMEHASH)
        return;

    i = CM_CELL_NAME_HASH(cellp->name);

    cellp->nameNextp = cm_data.cellNameHashTablep[i];
    cm_data.cellNameHashTablep[i] = cellp;
    _InterlockedOr(&cellp->flags, CM_CELLFLAG_IN_NAMEHASH);
}
Exemplo n.º 13
0
/* utility function to wakeup someone sleeping in SleepSched */
void osi_WakeupSpin(LONG_PTR sleepValue)
{
    LONG_PTR idx;
    CRITICAL_SECTION *csp;
    osi_sleepInfo_t *tsp;

    idx = osi_SLEEPHASH(sleepValue);
    csp = &osi_critSec[idx];
    EnterCriticalSection(csp);
    for(tsp=osi_sleepers[idx]; tsp; tsp=(osi_sleepInfo_t *) osi_QNext(&tsp->q)) {
        if ((!(tsp->states & (OSI_SLEEPINFO_DELETED|OSI_SLEEPINFO_SIGNALLED)))
             && tsp->value == sleepValue) {
            _InterlockedOr(&tsp->states, OSI_SLEEPINFO_SIGNALLED);
            ReleaseSemaphore(tsp->sema, 1, NULL);
        }
    }
    LeaveCriticalSection(csp);
}
Exemplo n.º 14
0
static void
cm_MarkServerDown(cm_server_t *tsp, afs_int32 code, int wasDown)
{

    /* mark server as down */
    if (!(tsp->flags & CM_SERVERFLAG_DOWN)) {
	_InterlockedOr(&tsp->flags, CM_SERVERFLAG_DOWN);
	tsp->downTime = time(NULL);
    }
    if (code != VRESTARTING) {
	lock_ReleaseMutex(&tsp->mx);
	cm_ForceNewConnections(tsp);
	lock_ObtainMutex(&tsp->mx);
    }
    /* Now update the volume status if necessary */
    if (!wasDown) {
	if (tsp->type == CM_SERVER_FILE) {
	    cm_server_vols_t * tsrvp;
	    cm_volume_t * volp;
	    int i;
	    cm_req_t req;

	    for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
		for (i=0; i<NUM_SERVER_VOLS; i++) {
		    if (tsrvp->ids[i] != 0) {
			cm_InitReq(&req);

			lock_ReleaseMutex(&tsp->mx);
			code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i],
						 cm_rootUserp, &req,
						 CM_GETVOL_FLAG_NO_LRU_UPDATE,
						 &volp);
			lock_ObtainMutex(&tsp->mx);
			if (code == 0) {
			    cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
			    cm_PutVolume(volp);
			}
		    }
		}
	    }
	}
	cm_RankServer(tsp);
    }
}
Exemplo n.º 15
0
BOOL Condition::Wait(DWORD timeout)
{
// 参考程度の空き開始位置調査
// (正確な確認は、INIT_EVENT <-> WAIT_EVENT の CAS で)
	u_int	idx = get_ntz(_InterlockedExchangeAdd(&gEventMap, 0));
	u_int	self_bit = 0;
	if (idx >= MaxThreads) idx = 0;

	int	count = 0;
	while (count < MaxThreads) {
		if (InterlockedCompareExchange(&gEvents[idx].kind, WAIT_EVENT, INIT_EVENT) == INIT_EVENT) {
			self_bit = 1 << idx;
			_InterlockedAnd(&gEventMap, ~self_bit);
			break;
		}
		if (++idx == MaxThreads) idx = 0;
		count++;
	}
	if (count >= MaxThreads) {	// 通常はありえない
		MessageBox(0, "Detect too many wait threads", "TLib", MB_OK);
		return	FALSE;
	}
	Event	&event = gEvents[idx];

	if (event.hEvent == NULL) {
		event.hEvent = ::CreateEvent(0, FALSE, FALSE, NULL);
	}
	waitBits |= self_bit;

	UnLock();

	DWORD	status = ::WaitForSingleObject(event.hEvent, timeout);

	Lock();
	waitBits &= ~self_bit;
	InterlockedExchange(&event.kind, INIT_EVENT);
	_InterlockedOr(&gEventMap, self_bit);

	return	status == WAIT_TIMEOUT ? FALSE : TRUE;
}
Exemplo n.º 16
0
	/* _Atomic_fetch_or_4 */
_Uint4_t _Fetch_or_seq_cst_4(volatile _Uint4_t *_Tgt, _Uint4_t _Value)
	{	/* or _Value with *_Tgt atomically with
			sequentially consistent memory order */
	_Value = _InterlockedOr((volatile long *)_Tgt, _Value);
	return (_Value);
	}
Exemplo n.º 17
0
cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags)
{
    cm_cell_t *cp, *cp2;
    long code;
    char fullname[CELL_MAXNAMELEN]="";
    char linkedName[CELL_MAXNAMELEN]="";
    char name[CELL_MAXNAMELEN]="";
    int  hasWriteLock = 0;
    int  hasMutex = 0;
    afs_uint32 hash;
    cm_cell_rock_t rock;
    size_t len;

    if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH))
        return NULL;

    /*
     * Strip off any trailing dots at the end of the cell name.
     * Failure to do so results in an undesireable alias as the
     * result of DNS AFSDB record lookups where a trailing dot
     * has special meaning.
     */
    strncpy(name, namep, CELL_MAXNAMELEN);
    for (len = strlen(namep); len > 0 && namep[len-1] == '.'; len--) {
        name[len-1] = '\0';
    }
    if (len == 0)
        return NULL;
    namep = name;

    hash = CM_CELL_NAME_HASH(namep);

    lock_ObtainRead(&cm_cellLock);
    for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
        if (cm_stricmp_utf8(namep, cp->name) == 0) {
            strncpy(fullname, cp->name, CELL_MAXNAMELEN);
            fullname[CELL_MAXNAMELEN-1] = '\0';
            break;
        }
    }

    if (!cp) {
        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }
    }

    if (cp) {
        lock_ReleaseRead(&cm_cellLock);
        cm_UpdateCell(cp, flags);
    } else if (flags & CM_FLAG_CREATE) {
        lock_ConvertRToW(&cm_cellLock);
        hasWriteLock = 1;

        /* when we dropped the lock the cell could have been added
         * to the list so check again while holding the write lock
         */
        for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) {
            if (cm_stricmp_utf8(namep, cp->name) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp)
            goto done;

        for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) {
            if (strnicmp(namep, cp->name, strlen(namep)) == 0) {
                strncpy(fullname, cp->name, CELL_MAXNAMELEN);
                fullname[CELL_MAXNAMELEN-1] = '\0';
                break;
            }
        }

        if (cp) {
            lock_ReleaseWrite(&cm_cellLock);
            lock_ObtainMutex(&cp->mx);
            lock_ObtainWrite(&cm_cellLock);
            cm_AddCellToNameHashTable(cp);
            cm_AddCellToIDHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            goto done;
        }

        if ( cm_data.freeCellsp != NULL ) {
            cp = cm_data.freeCellsp;
            cm_data.freeCellsp = cp->freeNextp;

            /*
             * The magic, cellID, and mx fields are already set.
             */
        } else {
            if ( cm_data.currentCells >= cm_data.maxCells )
                osi_panic("Exceeded Max Cells", __FILE__, __LINE__);

            /* don't increment currentCells until we know that we
             * are going to keep this entry
             */
            cp = &cm_data.cellBaseAddress[cm_data.currentCells];
            memset(cp, 0, sizeof(cm_cell_t));
            cp->magic = CM_CELL_MAGIC;

            /* the cellID cannot be 0 */
            cp->cellID = ++cm_data.currentCells;

            /* otherwise we found the cell, and so we're nearly done */
            lock_InitializeMutex(&cp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL);
        }

        lock_ReleaseWrite(&cm_cellLock);
        hasWriteLock = 0;

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock);
        if (code) {
            osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s",
                      osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname),
                      osi_LogSaveString(afsd_logp,linkedName));

            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, &rock);
                if ( code ) {
                    osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s",
                             osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname));
                    lock_ObtainMutex(&cp->mx);
                    lock_ObtainWrite(&cm_cellLock);
                    hasWriteLock = 1;
                    cm_RemoveCellFromIDHashTable(cp);
                    cm_RemoveCellFromNameHashTable(cp);
                    lock_ReleaseMutex(&cp->mx);
                    cm_FreeCell(cp);
                    cp = NULL;
                    goto done;
                } else {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    hasMutex = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
                    cp->timeout = time(0) + ttl;
                }
            }
            else
            {
                lock_ObtainMutex(&cp->mx);
                lock_ObtainWrite(&cm_cellLock);
                hasWriteLock = 1;
                cm_RemoveCellFromIDHashTable(cp);
                cm_RemoveCellFromNameHashTable(cp);
                lock_ReleaseMutex(&cp->mx);
                cm_FreeCell(cp);
                cp = NULL;
                goto done;
	    }
        } else {
            lock_ObtainMutex(&cp->mx);
            hasMutex = 1;
	    cp->timeout = time(0) + 7200;	/* two hour timeout */
	}

        /* we have now been given the fullname of the cell.  It may
         * be that we already have a cell with that name.  If so,
         * we should use it instead of completing the allocation
         * of a new cm_cell_t
         */
        lock_ObtainRead(&cm_cellLock);
        hash = CM_CELL_NAME_HASH(fullname);
        for (cp2 = cm_data.cellNameHashTablep[hash]; cp2; cp2=cp2->nameNextp) {
            if (cm_stricmp_utf8(fullname, cp2->name) == 0) {
                break;
            }
        }

        if (cp2) {
            if (!hasMutex) {
                lock_ObtainMutex(&cp->mx);
                hasMutex = 1;
            }
            lock_ConvertRToW(&cm_cellLock);
            hasWriteLock = 1;
            cm_RemoveCellFromIDHashTable(cp);
            cm_RemoveCellFromNameHashTable(cp);
            lock_ReleaseMutex(&cp->mx);
            hasMutex = 0;
            cm_FreeCell(cp);
            cp = cp2;
            goto done;
        }
        lock_ReleaseRead(&cm_cellLock);

        /* randomise among those vlservers having the same rank*/
        cm_RandomizeServer(&cp->vlServersp);

        if (!hasMutex)
            lock_ObtainMutex(&cp->mx);

        /* copy in name */
        strncpy(cp->name, fullname, CELL_MAXNAMELEN);
        cp->name[CELL_MAXNAMELEN-1] = '\0';

        strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN);
        cp->linkedName[CELL_MAXNAMELEN-1] = '\0';

        lock_ObtainWrite(&cm_cellLock);
        hasWriteLock = 1;
        cm_AddCellToNameHashTable(cp);
        cm_AddCellToIDHashTable(cp);
        lock_ReleaseMutex(&cp->mx);
        hasMutex = 0;

        /* append cell to global list */
        if (cm_data.allCellsp == NULL) {
            cm_data.allCellsp = cp;
        } else {
            for (cp2 = cm_data.allCellsp; cp2->allNextp; cp2=cp2->allNextp)
                ;
            cp2->allNextp = cp;
        }
        cp->allNextp = NULL;

    } else {
        lock_ReleaseRead(&cm_cellLock);
    }
  done:
    if (hasMutex && cp)
        lock_ReleaseMutex(&cp->mx);
    if (hasWriteLock)
        lock_ReleaseWrite(&cm_cellLock);

    /* fullname is not valid if cp == NULL */
    if (newnamep) {
        if (cp) {
            strncpy(newnamep, fullname, CELL_MAXNAMELEN);
            newnamep[CELL_MAXNAMELEN-1]='\0';
        } else {
            newnamep[0] = '\0';
        }
    }

    if (cp && cp->linkedName[0]) {
        cm_cell_t * linkedCellp = NULL;

        if (!strcmp(cp->name, cp->linkedName)) {
            cp->linkedName[0] = '\0';
        } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) {
            linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE);

            lock_ObtainWrite(&cm_cellLock);
            if (!linkedCellp ||
                (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) {
                cp->linkedName[0] = '\0';
            } else {
                strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN);
                linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0';
            }
            lock_ReleaseWrite(&cm_cellLock);
        }
    }
    return cp;
}
Exemplo n.º 18
0
BOOLEAN
AmccPciEvtInterruptIsr(
    __in WDFINTERRUPT Interrupt,
    __in ULONG        MessageID
    )
/*++

Routine Description:

    This routine assumes that only a single I/O can be completed at a
    time on the hardware (i.e. at most one I/O completed per interrupt).

Arguments:

    Interupt - Address of the framework interrupt object
    MessageID -

Return Value:

    TRUE - Interrupt belongs to this device.

--*/
{
    PAMCC_DEVICE_EXTENSION   devExt = NULL;
    WDFDEVICE                hDevice;

    union {
        ULONG      ulong;
        INTCSR_REG bits;
    } intcsr;

    union {
        ULONG      ulong;
        MCSR_REG   bits;
    } mcsr;

    UNREFERENCED_PARAMETER( MessageID );

    hDevice = WdfInterruptGetDevice(Interrupt);
    devExt = AmccPciGetDevExt(hDevice);

    //
    // Read interrupt control/status register and see if an interrupt is pending.
    // If not, return FALSE immediately.
    //
    intcsr.ulong = READ_PORT_ULONG((PULONG) &devExt->Regs->INTCSR);

    if (!intcsr.bits.InterruptAsserted) {
        return FALSE;
    }

    //
    // Disable bus-mastering
    //
    mcsr.ulong = READ_PORT_ULONG((PULONG) &devExt->Regs->MCSR);

    mcsr.bits.WriteTransferEnable = FALSE;
    mcsr.bits.ReadTransferEnable  = FALSE;

    WRITE_PORT_ULONG((PULONG) &devExt->Regs->MCSR, mcsr.ulong );

    //
    // This will take effect when INTCSR is rewritten later.
    //
    intcsr.bits.IntOnWriteTransferComplete = FALSE;
    intcsr.bits.IntOnReadTransferComplete  = FALSE;

    //
    // Process pending interrupts. We're expecting an interrupt due
    // to a transfer count going to zero, but we might be getting a
    // master or target abort instead.
    //
    while (intcsr.bits.InterruptAsserted) {

        //
        // Merge new interrupts with old
        //
        _InterlockedOr((PLONG) &devExt->Intcsr, (LONG) intcsr.ulong );

        //
        // Interrupt flags on the S5933 are cleared by writing a "1" bit
        // to them, so clear all the interrupts just examined.
        //
        WRITE_PORT_ULONG((PULONG) &devExt->Regs->INTCSR, intcsr.ulong);

        //
        // Check for additional interrupts
        //
        intcsr.ulong = READ_PORT_ULONG((PULONG) &devExt->Regs->INTCSR);
    }

    //
    // Check if there is a current Request.  If not, then this interrupt cannot
    // do anything.  This driver design requires an I/O to be pending in order
    // to queue the DPC.  If there is no I/O current, then there is no need
    // to have a DPC queued.  This driver also assumes one I/O per interrupt.
    //
    // IMPORTANT: Before returning TRUE, the interrupt must have been cleared
    // on the device or the system will hang trying to service this level
    // sensitive interrupt.
    //
    if (!devExt->CurrentRequest) {
        TraceEvents(TRACE_LEVEL_WARNING, AMCC_TRACE_IO,
                    "Hardware generated interrupt with no request pending");
        return TRUE;
    }

    //
    // Request the DPC to complete the transfer.
    //
    WdfInterruptQueueDpcForIsr( Interrupt );

    //
    // Indicate that this adapter was interrupting.
    //
    return TRUE;
}
Exemplo n.º 19
0
/* special turnstile signal for mutexes and locks.  Wakes up only those who
 * will really be able to lock the lock.  The assumption is that everyone who
 * already can use the lock has already been woken (and is thus not in the
 * turnstile any longer).
 *
 * The stillHaveReaders parm is set to 1 if this is a convert from write to read,
 * indicating that there is still at least one reader, and we should only wake
 * up other readers.  We use it in a tricky manner: we just pretent we already woke
 * a reader, and that is sufficient to prevent us from waking a writer.
 *
 * The crit sec. csp is released before the threads are woken, but after they
 * are removed from the turnstile.  It helps ensure that we won't have a spurious
 * context swap back to us if the release performs a context swap for some reason.
 */
void osi_TSignalForMLs(osi_turnstile_t *turnp, int stillHaveReaders, CRITICAL_SECTION *csp)
{
    osi_sleepInfo_t *tsp;		/* a temp */
    osi_sleepInfo_t *nsp;		/* a temp */
    osi_queue_t *wakeupListp;	/* list of dudes to wakeup after dropping lock */
    int wokeReader;
    unsigned short *sp;
    unsigned char *cp;

    wokeReader = stillHaveReaders;
    wakeupListp = NULL;
    while(tsp = turnp->lastp) {
        /* look at each sleepInfo until we find someone we're not supposed to
         * wakeup.
         */
        if (tsp->waitFor & OSI_SLEEPINFO_W4WRITE) {
            if (wokeReader)
                break;
        }
        else
            wokeReader = 1;

        /* otherwise, we will wake this guy.  For now, remove from this list
         * and move to private one, so we can do the wakeup after releasing
         * the crit sec.
         */
        osi_QRemoveHT((osi_queue_t **) &turnp->firstp, (osi_queue_t **) &turnp->lastp, &tsp->q);

        /* do the patching required for lock obtaining */
        if (tsp->waitFor & OSI_SLEEPINFO_W4WRITE) {
            cp = (void *) tsp->value;
            (*cp) |= OSI_LOCKFLAG_EXCL;
            tsp->tidp[0] = tsp->tid;
        }
        else if (tsp->waitFor & OSI_SLEEPINFO_W4READ) {
            sp = (void *) tsp->value;
#ifdef DEBUG
            if ((*sp) < OSI_RWLOCK_THREADS)
                tsp->tidp[*sp] = tsp->tid;
#endif
            (*sp)++;
        }

        /* and add to our own list */
        tsp->q.nextp = wakeupListp;
        wakeupListp = &tsp->q;

        /* now if we woke a writer, we're done, since it is pointless
         * to wake more than one writer.
         */
        if (!wokeReader)
            break;
    }

    /* hit end, or found someone we're not supposed to wakeup */
    if (csp)
        LeaveCriticalSection(csp);

        /* finally, wakeup everyone we found.  Don't free things since the sleeper
         * will free the sleepInfo structure.
         */
	for(tsp = (osi_sleepInfo_t *) wakeupListp; tsp; tsp = nsp) {
            /* pull this out first, since *tsp *could* get freed immediately
             * after the ReleaseSemaphore, if a context swap occurs.
             */
            nsp = (osi_sleepInfo_t *) tsp->q.nextp;
            _InterlockedOr(&tsp->states, OSI_SLEEPINFO_SIGNALLED);
            ReleaseSemaphore(tsp->sema, 1, NULL);
        }
}
Exemplo n.º 20
0
LONG test_InterlockedOr(LONG volatile *value, LONG mask) {
  return _InterlockedOr(value, mask);
}
Exemplo n.º 21
0
long test_InterlockedOr(long volatile *value, long mask) {
  return _InterlockedOr(value, mask);
}
Exemplo n.º 22
0
static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp)
{
    /*
     * The goal of this function is to probe simultaneously
     * probe all of the up/down servers (vldb/file) as
     * specified by flags in the minimum number of RPCs.
     * Effectively that means use one multi_RXAFS_GetCapabilities()
     * followed by possibly one multi_RXAFS_GetTime() and
     * one multi_VL_ProbeServer().
     *
     * To make this work we must construct the list of vldb
     * and file servers that are to be probed as well as the
     * associated data structures.
     */

    int srvAddrCount = 0;
    struct srvAddr **addrs = NULL;
    cm_conn_t **conns = NULL;
    struct rx_connection **rxconns = NULL;
    cm_req_t req;
    afs_int32 i, nconns = 0, maxconns;
    afs_int32 *conntimer, *results;
    Capabilities *caps = NULL;
    cm_server_t ** serversp, *tsp;
    afs_uint32 isDown, wasDown;
    afs_uint32 code;
    time_t start;
    char hoststr[16];

    cm_InitReq(&req);
    maxconns = max(cm_numFileServers,cm_numVldbServers);
    if (maxconns == 0)
        return;

    conns = (cm_conn_t **)malloc(maxconns * sizeof(cm_conn_t *));
    rxconns = (struct rx_connection **)malloc(maxconns * sizeof(struct rx_connection *));
    conntimer = (afs_int32 *)malloc(maxconns * sizeof (afs_int32));
    results = (afs_int32 *)malloc(maxconns * sizeof (afs_int32));
    serversp = (cm_server_t **)malloc(maxconns * sizeof(cm_server_t *));
    caps = (Capabilities *)malloc(maxconns * sizeof(Capabilities));

    memset(caps, 0, maxconns * sizeof(Capabilities));

    if ((flags & CM_FLAG_CHECKFILESERVERS) ||
        !(flags & (CM_FLAG_CHECKFILESERVERS|CM_FLAG_CHECKVLDBSERVERS)))
    {
        lock_ObtainRead(&cm_serverLock);
	for (nconns=0, tsp = cm_serversAllFirstp;
	      tsp != NULL && nconns < maxconns;
	      tsp = (cm_server_t *)osi_QNext(&tsp->allq)) {
            if (tsp->type != CM_SERVER_FILE ||
                tsp->cellp == NULL ||           /* SetPref only */
                cellp && cellp != tsp->cellp)
                continue;

            cm_GetServerNoLock(tsp);
            lock_ReleaseRead(&cm_serverLock);

            lock_ObtainMutex(&tsp->mx);
            isDown = tsp->flags & CM_SERVERFLAG_DOWN;

            if ((tsp->flags & CM_SERVERFLAG_PINGING) ||
                !((isDown && (flags & CM_FLAG_CHECKDOWNSERVERS)) ||
                   (!isDown && (flags & CM_FLAG_CHECKUPSERVERS)))) {
                lock_ReleaseMutex(&tsp->mx);
                lock_ObtainRead(&cm_serverLock);
                cm_PutServerNoLock(tsp);
                continue;
            }

            _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PINGING);
            lock_ReleaseMutex(&tsp->mx);

            serversp[nconns] = tsp;
	    if (cm_noIPAddr > 0)
		code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &conns[nconns]);
	    else
		code = RX_CALL_DEAD;
            if (code) {
		if (code == RX_CALL_DEAD) {
		    lock_ObtainMutex(&tsp->mx);
		    cm_MarkServerDown(tsp, code, isDown);
		    lock_ReleaseMutex(&tsp->mx);
		}
		lock_ObtainRead(&cm_serverLock);
		cm_PutServerNoLock(tsp);
                continue;
            }
            lock_ObtainRead(&cm_serverLock);
            rxconns[nconns] = cm_GetRxConn(conns[nconns]);
            if (conntimer[nconns] = (isDown ? 1 : 0))
                rx_SetConnHardDeadTime(rxconns[nconns], 10);

            nconns++;
        }
        lock_ReleaseRead(&cm_serverLock);

        if (nconns) {
            /* Perform the multi call */
            start = time(NULL);
            multi_Rx(rxconns,nconns)
            {
                multi_RXAFS_GetCapabilities(&caps[multi_i]);
                results[multi_i]=multi_error;
            } multi_End;
        }
Exemplo n.º 23
0
long
cm_CreateCellWithInfo( char * cellname,
                       char * linked_cellname,
                       unsigned short vlport,
                       afs_uint32 host_count,
                       char *hostname[],
                       afs_uint32 flags)
{
    afs_uint32 code = 0;
    cm_cell_rock_t rock;
    struct hostent *thp;
    struct sockaddr_in vlSockAddr;
    afs_uint32 i, j;

    rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE);
    rock.flags = 0;

    cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE);

    if (!(flags & CM_CELLFLAG_DNS)) {
        for (i = 0; i < host_count; i++) {
            thp = gethostbyname(hostname[i]);
            if (thp) {
                int foundAddr = 0;
                for (j=0 ; thp->h_addr_list[j]; j++) {
                    if (thp->h_addrtype != AF_INET)
                        continue;
                    memcpy(&vlSockAddr.sin_addr.s_addr,
                           thp->h_addr_list[j],
                           sizeof(long));
                    vlSockAddr.sin_port = htons(vlport ? vlport : 7003);
                    vlSockAddr.sin_family = AF_INET;
                    cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE);
                }
            }
        }
        lock_ObtainMutex(&rock.cellp->mx);
        _InterlockedAnd(&rock.cellp->flags, ~CM_CELLFLAG_DNS);
    } else if (cm_dnsEnabled) {
        int ttl;

        code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock);
        lock_ObtainMutex(&rock.cellp->mx);
        if (code == 0) {   /* got cell from DNS */
            _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_DNS);
            rock.cellp->timeout = time(0) + ttl;
#ifdef DEBUG
            fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl);
#endif
        }
    } else {
        lock_ObtainMutex(&rock.cellp->mx);
        rock.cellp->flags &= ~CM_CELLFLAG_DNS;
    }
    _InterlockedOr(&rock.cellp->flags, CM_CELLFLAG_VLSERVER_INVALID);
    StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname);
    lock_ReleaseMutex(&rock.cellp->mx);

    if (rock.cellp->vlServersp)
        cm_RandomizeServer(&rock.cellp->vlServersp);

    return code;
}
Exemplo n.º 24
0
Int32 KInterlockedOr(Int32 volatile* var, Int32 add)
{
    return _InterlockedOr((volatile long*)var, add);
}
Exemplo n.º 25
0
/* if it's from DNS, see if it has expired
 * and check to make sure we have a valid set of volume servers
 * this function must not be called with a lock on cm_cellLock
 */
cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags)
{
    long code = 0;
    cm_cell_rock_t rock;
    afs_uint32 mxheld = 0;

    if (cp == NULL)
        return NULL;

    lock_ObtainMutex(&cp->mx);
    mxheld = 1;

#ifdef AFS_FREELANCE_CLIENT
    if (cp->flags & CM_CELLFLAG_FREELANCE) {
        lock_ReleaseMutex(&cp->mx);
        return cp;
    }
#endif

    if (cm_IsServerListEmpty(cp->vlServersp) ||
        (time(0) > cp->timeout) ||
        (cm_dnsEnabled &&
         (cp->flags & CM_CELLFLAG_DNS) &&
         ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID))))
    {
        lock_ReleaseMutex(&cp->mx);
        mxheld = 0;

        /* must empty cp->vlServersp */
        if (cp->vlServersp)
            cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);

        rock.cellp = cp;
        rock.flags = flags;
        code = cm_SearchCellRegistry(1, cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
            code = cm_SearchCellFileEx(cp->name, NULL, cp->linkedName, cm_AddCellProc, &rock);
        if (code == 0) {
            lock_ObtainMutex(&cp->mx);
            mxheld = 1;
	    cp->timeout = time(0) + 7200;
        }
        else {
            if (cm_dnsEnabled) {
                int ttl;

                code = cm_SearchCellByDNS(cp->name, NULL, &ttl, cm_AddCellProc, &rock);
                if (code == 0) {   /* got cell from DNS */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS);
                    _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID);
		    cp->timeout = time(0) + ttl;
#ifdef DEBUG
                    fprintf(stderr, "cell %s: ttl=%d\n", cp->name, ttl);
#endif
		} else {
                    /* if we fail to find it this time, we'll just do nothing and leave the
                     * current entry alone
		     */
                    lock_ObtainMutex(&cp->mx);
                    mxheld = 1;
                    _InterlockedOr(&cp->flags, CM_CELLFLAG_VLSERVER_INVALID);
                }
	    }
	}
    }

    if (code == 0)
        cm_RandomizeServer(&cp->vlServersp);

    if (mxheld)
        lock_ReleaseMutex(&cp->mx);

    return code ? NULL : cp;
}
Exemplo n.º 26
0
void
cm_PingServer(cm_server_t *tsp)
{
    long code;
    int wasDown = 0;
    cm_conn_t *connp;
    struct rx_connection * rxconnp;
    Capabilities caps = {0, 0};
    char hoststr[16];
    cm_req_t req;

    lock_ObtainMutex(&tsp->mx);
    if (tsp->flags & CM_SERVERFLAG_PINGING) {
	tsp->waitCount++;
	osi_SleepM((LONG_PTR)tsp, &tsp->mx);
	lock_ObtainMutex(&tsp->mx);
	tsp->waitCount--;
	if (tsp->waitCount == 0)
	    _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
	else
	    osi_Wakeup((LONG_PTR)tsp);
	lock_ReleaseMutex(&tsp->mx);
	return;
    }
    _InterlockedOr(&tsp->flags, CM_SERVERFLAG_PINGING);
    wasDown = tsp->flags & CM_SERVERFLAG_DOWN;
    afs_inet_ntoa_r(tsp->addr.sin_addr.S_un.S_addr, hoststr);
    lock_ReleaseMutex(&tsp->mx);

    if (cm_noIPAddr > 0)
	code = cm_ConnByServer(tsp, cm_rootUserp, FALSE, &connp);
    else
	code = RX_CALL_DEAD;	/* No network */
    if (code == 0) {
	/* now call the appropriate ping call.  Drop the timeout if
	* the server is known to be down, so that we don't waste a
	* lot of time retiming out down servers.
	*/

	osi_Log4(afsd_logp, "cm_PingServer server %s (%s) was %s with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  wasDown ? "down" : "up",
		  tsp->capabilities);

        rxconnp = cm_GetRxConn(connp);
	if (wasDown)
	    rx_SetConnHardDeadTime(rxconnp, 10);
	if (tsp->type == CM_SERVER_VLDB) {
	    code = VL_ProbeServer(rxconnp);
	}
	else {
	    /* file server */
	    code = RXAFS_GetCapabilities(rxconnp, &caps);
	}
	if (wasDown)
	    rx_SetConnHardDeadTime(rxconnp, HardDeadtimeout);
        rx_PutConnection(rxconnp);
	cm_PutConn(connp);
    }	/* got an unauthenticated connection to this server */

    lock_ObtainMutex(&tsp->mx);
    if (code >= 0 || code == RXGEN_OPCODE || code == RX_CALL_BUSY) {
	/* mark server as up */
	_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN);
        tsp->downTime = 0;

	/* we currently handle 32-bits of capabilities */
	if (code != RXGEN_OPCODE && code != RX_CALL_BUSY &&
            caps.Capabilities_len > 0) {
	    tsp->capabilities = caps.Capabilities_val[0];
	    xdr_free((xdrproc_t) xdr_Capabilities, &caps);
	    caps.Capabilities_len = 0;
	    caps.Capabilities_val = 0;
	} else {
	    tsp->capabilities = 0;
	}

	osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is up with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  tsp->capabilities);

        /* Now update the volume status if necessary */
        if (wasDown) {
            cm_server_vols_t * tsrvp;
            cm_volume_t * volp;
            int i;

            for (tsrvp = tsp->vols; tsrvp; tsrvp = tsrvp->nextp) {
                for (i=0; i<NUM_SERVER_VOLS; i++) {
                    if (tsrvp->ids[i] != 0) {
                        cm_InitReq(&req);

                        lock_ReleaseMutex(&tsp->mx);
                        code = cm_FindVolumeByID(tsp->cellp, tsrvp->ids[i], cm_rootUserp,
                                                &req, CM_GETVOL_FLAG_NO_LRU_UPDATE, &volp);
                        lock_ObtainMutex(&tsp->mx);
                        if (code == 0) {
                            cm_UpdateVolumeStatus(volp, tsrvp->ids[i]);
                            cm_PutVolume(volp);
                        }
                    }
                }
            }
            cm_RankServer(tsp);
        }
    } else {
	cm_MarkServerDown(tsp, code, wasDown);

	osi_Log3(afsd_logp, "cm_PingServer server %s (%s) is down with caps 0x%x",
		  osi_LogSaveString(afsd_logp, hoststr),
		  tsp->type == CM_SERVER_VLDB ? "vldb" : "file",
		  tsp->capabilities);
    }

    if (tsp->waitCount == 0)
	_InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_PINGING);
    else
	osi_Wakeup((LONG_PTR)tsp);
    lock_ReleaseMutex(&tsp->mx);
}