Ejemplo n.º 1
0
Archivo: taskwd.c Proyecto: ukaea/epics
epicsShareFunc void taskwdShow(int level)
{
    struct tNode *pt;
    int mCount, fCount, tCount;
    char tName[40];

    epicsMutexMustLock(mLock);
    mCount = ellCount(&mList);
    epicsMutexUnlock(mLock);

    epicsMutexMustLock(fLock);
    fCount = ellCount(&fList);
    epicsMutexUnlock(fLock);

    epicsMutexMustLock(tLock);
    tCount = ellCount(&tList);
    printf("%d monitors, %d threads registered, %d free nodes\n",
        mCount, tCount, fCount);
    if (level) {
        printf("%16.16s %9s %12s %12s %12s\n",
            "THREAD NAME", "STATE", "EPICS TID", "CALLBACK", "USR ARG");
        pt = (struct tNode *)ellFirst(&tList);
        while (pt != NULL) {
            epicsThreadGetName(pt->tid, tName, sizeof(tName));
            printf("%16.16s %9s %12p %12p %12p\n",
                tName, pt->suspended ? "Suspended" : "Ok ",
                (void *)pt->tid, (void *)pt->callback, pt->usr);
            pt = (struct tNode *)ellNext(&pt->node);
        }
    }
    epicsMutexUnlock(tLock);
}
Ejemplo n.º 2
0
void ThreadList::dump() const
{
    char name[100];
    epicsThreadGetName(thread, name, sizeof(name));
    fprintf(stderr, "Thread '%s': ", name);
    bool first = true;
    stdList<const OrderedMutex *>::const_iterator i;
    for (i = locks.begin();  i != locks.end();  ++i)
    {
        const OrderedMutex *l = *i;
        if (first)
            first = false;
        else
            fprintf(stderr, ", ");
        fprintf(stderr, "'%s' (%zu)", l->getName().c_str(), l->getOrder());
    }
    printf("\n");
}
Ejemplo n.º 3
0
Archivo: taskwd.c Proyecto: ukaea/epics
static void twdTask(void *arg)
{
    struct tNode *pt;
    struct mNode *pm;

    while (twdCtl != twdctlExit) {
        if (twdCtl == twdctlRun) {
            epicsMutexMustLock(tLock);
            pt = (struct tNode *)ellFirst(&tList);
            while (pt) {
                int susp = epicsThreadIsSuspended(pt->tid);
                if (susp != pt->suspended) {
                    epicsMutexMustLock(mLock);
                    pm = (struct mNode *)ellFirst(&mList);
                    while (pm) {
                        if (pm->funcs->notify) {
                            pm->funcs->notify(pm->usr, pt->tid, susp);
                        }
                        pm = (struct mNode *)ellNext(&pm->node);
                    }
                    epicsMutexUnlock(mLock);

                    if (susp) {
                        char tName[40];
                        epicsThreadGetName(pt->tid, tName, sizeof(tName));
                        errlogPrintf("Thread %s (%p) suspended\n",
                                    tName, (void *)pt->tid);
                        if (pt->callback) {
                            pt->callback(pt->usr);
                        }
                    }
                    pt->suspended = susp;
                }
                pt = (struct tNode *)ellNext(&pt->node);
            }
            epicsMutexUnlock(tLock);
        }
        epicsEventWaitWithTimeout(loopEvent, TASKWD_DELAY);
    }
    epicsEventSignal(exitEvent);
}
Ejemplo n.º 4
0
void
epicsEventShow(epicsEventId id, unsigned int level)
{
#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__
    rtems_id sid = (rtems_id)id;
    Semaphore_Control *the_semaphore;
    Semaphore_Control semaphore;
    Objects_Locations location;

    the_semaphore = _Semaphore_Get (sid, &location);
    if (location != OBJECTS_LOCAL)
        return;
    /*
     * Yes, there's a race condition here since an interrupt might
     * change things while the copy is in progress, but the information
     * is only for display, so it's not that critical.
     */
    semaphore = *the_semaphore;
    _Thread_Enable_dispatch();
    printf ("          %8.8x  ", (int)sid);
    if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) {
            printf ("Count: %d", (int)semaphore.Core_control.semaphore.count);
    }
    else {
        if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) {
            char name[30];
            epicsThreadGetName ((epicsThreadId)semaphore.Core_control.mutex.holder_id, name, sizeof name);
            printf ("Held by:%8.8x (%s)  Nest count:%d",
                                    (unsigned int)semaphore.Core_control.mutex.holder_id,
                                    name,
                                    (int)semaphore.Core_control.mutex.nest_count);
        }
        else {
            printf ("Not Held");
        }
    }
    printf ("\n");
#endif
}
Ejemplo n.º 5
0
Archivo: taskwd.c Proyecto: ukaea/epics
void taskwdRemove(epicsThreadId tid)
{
    struct tNode *pt;
    struct mNode *pm;
    char tName[40];

    taskwdInit();

    if (tid == 0)
       tid = epicsThreadGetIdSelf();

    epicsMutexMustLock(tLock);
    pt = (struct tNode *)ellFirst(&tList);
    while (pt != NULL) {
        if (tid == pt->tid) {
            ellDelete(&tList, (void *)pt);
            epicsMutexUnlock(tLock);
            freeNode((union twdNode *)pt);

            epicsMutexMustLock(mLock);
            pm = (struct mNode *)ellFirst(&mList);
            while (pm) {
                if (pm->funcs->remove) {
                    pm->funcs->remove(pm->usr, tid);
                }
                pm = (struct mNode *)ellNext(&pm->node);
            }
            epicsMutexUnlock(mLock);
            return;
        }
        pt = (struct tNode *)ellNext(&pt->node);
    }
    epicsMutexUnlock(tLock);

    epicsThreadGetName(tid, tName, sizeof(tName));
    errlogPrintf("taskwdRemove: Thread %s (%p) not registered!\n",
        tName, (void *)tid);
}
Ejemplo n.º 6
0
/*
 * sequencer() - Sequencer main thread entry point.
 */
void sequencer (void *arg)	/* ptr to original (global) state program table */
{
	PROG		*sp = (PROG *)arg;
	unsigned	nss;
	size_t		threadLen;
	char		threadName[THREAD_NAME_SIZE+10];

	/* Get this thread's id */
	sp->ss->threadId = epicsThreadGetIdSelf();

	/* Add the program to the program list */
	seqAddProg(sp);

	createOrAttachPvSystem(sp);

	if (!pvSysIsDefined(sp->pvSys))
	{
		sp->die = TRUE;
		goto exit;
	}

	/* Call sequencer init function to initialize variables. */
	sp->initFunc(sp);

	/* Initialize state set variables. In safe mode, copy variable
	   block to state set buffers. Must do all this before connecting. */
	if (optTest(sp, OPT_SAFE))
	{
		for (nss = 0; nss < sp->numSS; nss++)
		{
			SSCB	*ss = sp->ss + nss;
			memcpy(ss->var, sp->var, sp->varSize);
		}
	}

	/* Attach to PV system */
	pvSysAttach(sp->pvSys);

	/* Initiate connect & monitor requests to database channels, waiting
	   for all connections to be established if the option is set. */
	if (seq_connect(sp, optTest(sp, OPT_CONN) != pvStatOK))
		goto exit;

	/* Emulate the 'first monitor event' for anonymous PVs */
	if (optTest(sp, OPT_SAFE))
	{
		unsigned nch;
		for (nch=0; nch<sp->numChans; nch++)
			if (sp->chan[nch].syncedTo && !sp->chan[nch].dbch)
				seq_efSet(sp->ss, sp->chan[nch].syncedTo);
	}

	/* Call program entry function if defined.
	   Treat as if called from 1st state set. */
	if (sp->entryFunc) sp->entryFunc(sp->ss);

	/* Create each additional state set task (additional state set thread
	   names are derived from the first ss) */
	epicsThreadGetName(sp->ss->threadId, threadName, sizeof(threadName));
	threadLen = strlen(threadName);
	for (nss = 1; nss < sp->numSS; nss++)
	{
		SSCB		*ss = sp->ss + nss;
		epicsThreadId	tid;

		/* Form thread name from program name + state set number */
		sprintf(threadName+threadLen, "_%d", nss);

		/* Spawn the task */
		tid = epicsThreadCreate(
			threadName,			/* thread name */
			sp->threadPriority,		/* priority */
			sp->stackSize,			/* stack size */
			ss_entry,			/* entry point */
			ss);				/* parameter */

		DEBUG("Spawning additional state set thread %p: \"%s\"\n", tid, threadName);
	}

	/* First state set jumps directly to entry point */
	ss_entry(sp->ss);

	DEBUG("   Wait for other state sets to exit\n");
	for (nss = 1; nss < sp->numSS; nss++)
	{
		SSCB *ss = sp->ss + nss;
		epicsEventMustWait(ss->dead);
	}

	/* Call program exit function if defined.
	   Treat as if called from 1st state set. */
	if (sp->exitFunc) sp->exitFunc(sp->ss);

exit:
	DEBUG("   Disconnect all channels\n");
	seq_disconnect(sp);
	DEBUG("   Remove program instance from list\n");
	seqDelProg(sp);

	errlogSevPrintf(errlogInfo,
		"Instance %d of sequencer program \"%s\" terminated\n",
		sp->instance, sp->progName);

	/* Free all allocated memory */
	seq_free(sp);
}