Skip to content

Commit

Permalink
Merge branch 'eventmgr' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
okrieg committed Dec 12, 2011
2 parents fef0c9d + 785271f commit c6715f9
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 105 deletions.
3 changes: 2 additions & 1 deletion l0/EBBMgrPrim.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ EBBMgrPrimImp_createRep(CObjEBBRootMultiRef _self) {
return (EBBRep *)repRef;
}

void EBBMgrPrimInit() {
void
EBBMgrPrimInit() {
CObjEBBRootMultiImpRef rootRef;
EBBMgrPrimId id;

Expand Down
62 changes: 43 additions & 19 deletions l0/EventMgrPrim.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@
* THE SOFTWARE.
*/

/*
* The Event Manager (EM) is one of the primordial objects. The EM
* will be a fully distributed objects. Clients can register with the
* EM objects to handle specific events. That will cause a customized
* routine to be generated on each core, that will register itself
* with the PIC (programable interrupt controller) on that core.
* There is a one-to-one correspondence between event numbers and
* interrupts. This will allow a dispatch from an interrupt to an EBB
* to be highly efficient, and conversly all interrupts to be handled
* on EBBs. The interrupt routine will buy the EM's rep's stack, and
* then invoke the handler previously registered for that event with
* interrupts disabled.
*
* The current implementation is very simple, a shared table of
* handlers, no dynamically generated code yet. ... but wanted to
* document the plan.
*/

/*
* All event handling ebbs must conform to these types
* Any existing ebbs that want to handle events must be
Expand All @@ -38,14 +56,36 @@ CObject(EventHandler) {

typedef EventHandlerRef *EventHandlerId;

CObjInterface(EventMgrPrim) {
// get handler, possibly on this core, needed to dispatch interupt
EBBRC (*getHandler) (void *_self, uintptr_t eventNo, EventHandlerId *handler);
/*
* You need to be able to get the event location of the node you are
* running on. I am not making this a function on EventMgr, but
* rather a global function so its clear that its the EL of the
* current core and not the EL of the rep of the EventMgr
*
* For now, one-to-one mapping event location and pic location. Since
* this may change, we include the corresponding header file here.
*/
#include <l0/lrt/pic.h>
typedef uintptr_t EvntLoc;
inline static EvntLoc MyEL() { return lrt_pic_myid; }

/*
* key local to eventmgr for allocating specific reserved events/interrupt
* sources
*/
CObjInterface(EventMgrPrim) {
EBBRC (*registerHandler) (void *_self, uintptr_t eventNo,
EventHandlerId handler,
uintptr_t isrc);
EBBRC (*registerIPIHandler) (void *_self, EventHandlerId handler);


EBBRC (*allocEventNo) (void *_self, uintptr_t *eventNoPtr);

/*
* Eventually, this call should take remote cnores for IPI
*/
EBBRC (*dispatchIPI) (void *_self, EvntLoc el);
};

CObject(EventMgrPrim) {
Expand All @@ -56,21 +96,5 @@ typedef EventMgrPrimRef *EventMgrPrimId;
// the ID of the one and only event manager
extern EventMgrPrimId theEventMgrPrimId;

/*
* You need to be able to get the event location of the
* node you are running on. I am not making this a
* function on EventMgr, but rather a global function
* so its clear that its the EL of the current core and not
* the EL of the rep of the EventMgr
*/
typedef uintptr_t EvntLoc;

/*
* For now, one-to-one mapping event location
* and pic location. Since this may change,
* we include the corresponding header file here.
*/
#include <l0/lrt/pic.h>
inline static EvntLoc MyEL() { return lrt_pic_myid; }

#endif
104 changes: 31 additions & 73 deletions l0/EventMgrPrimImp.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,22 @@ HandlerInfoStruc handlerInfo[MAXEVENTS];
CObject(EventMgrPrimImp){
CObjInterface(EventMgrPrim) *ft;
CObjEBBRootMultiRef theRoot;
uintptr_t ipi_vec_no;
};


// define vector functions that map vectors to events
// each function call's the appropriate handler installed
// for the corresponding event that the vector is mapped to
// We use a simple direct map: vector 0 is mapped to event 0
// etc.
// etc. This function will eventually be per-rep, and will
// as part of the invocation grab the event stack out fo the rep.
// FIXME: make this a per-rep strucutre
#define VFUNC(i) \
static void vf##i(void) \
{ \
EventHandlerId handler; \
EBBCALL(theEventMgrPrimId, getHandler, i, &handler); \
EBBAssert(handler != NULL); \
EBBCALL(handler, handleEvent); \
EBBAssert(handlerInfo[i].id != NULL); \
EBBCALL(handlerInfo[i].id, handleEvent); \
}

VFUNC(0);
Expand Down Expand Up @@ -375,9 +376,14 @@ vfunc vfTbl[MAXEVENTS] = {


static EBBRC
EventMgrPrim_getHandler(void *_self, uintptr_t eventNo, EventHandlerId *handler)
EventMgrPrim_dispatchIPI(void *_self, EvntLoc el)
{
*handler = handlerInfo[eventNo].id;
if (el != MyEL()) {
EBB_LRT_printf("%s: sending remote IPI to node %ld\n",
__func__,
el);
}
lrt_pic_ipi(el);
return EBBRC_OK;
}

Expand All @@ -404,6 +410,19 @@ EventMgrPrim_registerHandler(void *_self, uintptr_t eventNo,
handlerInfo[eventNo].id = NULL;
return EBBRC_BADPARAMETER;
}
return 0;
}

static EBBRC
EventMgrPrim_registerIPIHandler(void *_self, EventHandlerId handler)
{
EventMgrPrimImpRef self = (EventMgrPrimImpRef)_self;

// install handler in event table
handlerInfo[self->ipi_vec_no].id = handler;

// map vector in pic
lrt_pic_mapipi(vfTbl[self->ipi_vec_no]);

return 0;
}
Expand All @@ -416,9 +435,10 @@ EventMgrPrim_allocEventNo(void *_self, uintptr_t *eventNoPtr)
}

CObjInterface(EventMgrPrim) EventMgrPrimImp_ftable = {
.getHandler = EventMgrPrim_getHandler,
.registerHandler = EventMgrPrim_registerHandler,
.registerIPIHandler = EventMgrPrim_registerIPIHandler,
.allocEventNo = EventMgrPrim_allocEventNo,
.dispatchIPI = EventMgrPrim_dispatchIPI,
};

static void
Expand All @@ -430,11 +450,12 @@ EventMgrPrimSetFT(EventMgrPrimImpRef o)
EventMgrPrimId theEventMgrPrimId;

static EBBRep *
EventMgrPrimImp_createRep(CObjEBBRootMultiRef _self) {
EventMgrPrimImp_createRep(CObjEBBRootMultiRef root) {
EventMgrPrimImpRef repRef;
EBBPrimMalloc(sizeof(*repRef), &repRef, EBB_MEM_DEFAULT);
EventMgrPrimSetFT(repRef);
repRef->theRoot = _self;
repRef->theRoot = root;
repRef->ipi_vec_no = lrt_pic_getIPIvec();
// initGTable(EventMgrPrimErrMF, 0);
return (EBBRep *)repRef;
}
Expand Down Expand Up @@ -463,66 +484,3 @@ EventMgrPrimImpInit(void)
return EBBRC_OK;
};

#if 0
static EBBRC
EventHandler_handleEvent(void *_self)
{
EBB_LRT_printf("Wheeeee Handler Invoked\n");
return 0;
};

static EBBRC
EventHandler_init(void *_self)
{
return 0;
};


static CObjInterface(EventHandler) EventHandler_ftable = {
.handleEvent = EventHandler_handleEvent,
.init = EventHandler_init
};


// change to dynamically allocate this
static EventHandlerId
CreateTestHandler()
{
EBBRC rc;
static EventHandler theRep;
EventHandlerRef repRef = &theRep;
static CObjEBBRootShared theRoot;
CObjEBBRootSharedRef rootRef = &theRoot;
EventHandlerId handlerId;

// setup function tables
CObjEBBRootSharedSetFT(rootRef);
repRef->ft = &EventHandler_ftable;

// setup my representative and root
repRef->ft->init(repRef);
// shared root knows about only one rep so we
// pass it along for it's init
rootRef->ft->init(rootRef, &theRep);

rc = EBBAllocPrimId(&handlerId);
EBBRCAssert(rc);

rc = CObjEBBBind(handlerId, rootRef);
EBBRCAssert(rc);

return handlerId;
}

/* move to a seperate file eventually, should not be imp specific */
void EventMgrPrimImpTest(void)
{
EventHandlerId handlerId;
int eventNo;

handlerId = CreateTestHandler();

EBBCALL(theEventMgrPrimId, allocEventNo, &eventNo);
EBBCALL(theEventMgrPrimId, registerHandler, eventNo, handlerId);
}
#endif
89 changes: 80 additions & 9 deletions l0/l0_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,108 @@
#include <l0/lrt/pic.h>
#include <l0/lrt/trans.h>
#include <l0/types.h>
#include <l0/sys/trans.h>
#include <l0/cobj/CObjEBB.h>
#include <l0/EBBMgrPrim.h>
#include <l0/MemMgr.h>
#include <l0/MemMgrPrim.h>
#include <l0/EventMgrPrim.h>
#include <l0/EventMgrPrimImp.h>
#include <l0/cobj/CObjEBBRoot.h>
#include <l0/cobj/CObjEBBRootMulti.h>
#include <l0/cobj/CObjEBBRootMultiImp.h>



extern void trans_init(void);

static EBBRC
ResetEventHandler_handleEvent(void *_self)
{
EBB_LRT_printf("On reset event\n");
// then invoke a method of BootInfo object on first message
// this object should gather boot information (sysfacts and boot args)
// and then get full blown primitive l0 EBBS up (perhaps by a hot swap)
EBB_LRT_printf("%s: ADD REST OF INIT CODE HERE!\n", __func__);
sleep(10);
LRT_EBBAssert(0);
return 0;
};
static EBBRC
ResetEventHandler_init(void *_self)
{
return 0;
};

CObject(ResetEventHandler) {
CObjInterface(EventHandler) *ft;
CObjEBBRootMultiRef theRoot;
};


static CObjInterface(EventHandler) ResetEventHandler_ftable = {
.handleEvent = ResetEventHandler_handleEvent,
.init = ResetEventHandler_init
};

static EBBRep *
ResetEventHandler_createRep(CObjEBBRootMultiRef _self) {
ResetEventHandlerRef repRef;
EBBPrimMalloc(sizeof(*repRef), &repRef, EBB_MEM_DEFAULT);
repRef->ft = &ResetEventHandler_ftable;
repRef->theRoot = _self;
// initGTable(EventMgrPrimErrMF, 0);
return (EBBRep *)repRef;
}

static EventHandlerId
InitResetEventHandler()
{
CObjEBBRootMultiImpRef rootRef;
EventHandlerId id;
static EventHandlerId theResetEventHandlerId=0;

if (__sync_bool_compare_and_swap(&theResetEventHandlerId, (EventHandlerId)0,
(EventHandlerId)-1)) {
CObjEBBRootMultiImpCreate(&rootRef, ResetEventHandler_createRep);
id = (EventHandlerId)EBBIdAlloc();
EBBAssert(id != NULL);

EBBIdBind((EBBId)id, CObjEBBMissFunc, (EBBMissArg) rootRef);
theResetEventHandlerId = id;
} else {
while (((volatile uintptr_t)theResetEventHandlerId)==-1);
}
return theResetEventHandlerId;
};


/*
* Three main EBB's are EBBMgrPrim, EventMgrPrim EBBMemMgrPrim
* There creation and initialization are interdependent and requires
* fancy footwork
*/
void
EBB_init()
{
/* Three main EBB's are EBBMgrPrim, EventMgrPrim EBBMemMgrPrim */
/* There creation and initialization are interdependent and requires */
/* fancy footwork */
EBBRC rc;
EventHandlerId ehid;

rc = EBBMemMgrPrimInit();
EBBRCAssert(rc);

// FIXME: no error?
EBBMgrPrimInit();

rc = EventMgrPrimImpInit();
EBBRCAssert(rc);

// then invoke a method of BootInfo object on first message
// this object should gather boot information (sysfacts and boot args)
// and then get full blown primitive l0 EBBS up (perhaps by a hot swap)
EBB_LRT_printf("%s: ADD REST OF INIT CODE HERE!\n", __func__);
sleep(10);
LRT_EBBAssert(0);
ehid = InitResetEventHandler();
EBBAssert(ehid != NULL);

COBJ_EBBCALL(theEventMgrPrimId, registerIPIHandler, ehid);
COBJ_EBBCALL(theEventMgrPrimId, dispatchIPI, MyEL());
// will fall through
}

void
Expand Down
9 changes: 8 additions & 1 deletion l0/lrt/ulnx/pic.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ lrt_pic_disable(uintptr_t vec)
if (vec != RST_VEC) lrt_pic_set_remove(pic.vecs[vec].set, lrt_pic_myid);
}

uintptr_t
lrt_pic_getIPIvec(void)
{
return IPI_VEC;
}


void
lrt_pic_enableipi(void)
{
Expand Down Expand Up @@ -219,7 +226,7 @@ lrt_pic_init(lrt_pic_handler h)
lrt_pic_mapreset(h);

// fall into loop
lrt_pic_loop( );
lrt_pic_loop();

assert(0);

Expand Down
Loading

0 comments on commit c6715f9

Please sign in to comment.