slc-aware ioc

32
Diane Fairley 11/11/2004 Slc-aware Ioc SLC Executive Message Service

Upload: tom

Post on 12-Jan-2016

28 views

Category:

Documents


0 download

DESCRIPTION

Slc-aware Ioc. SLC Executive Message Service. SLC Executive. Slc-aware IOC Initialization The SLC Executive Thread Startup Process Shutdown Process Some General Thread Issues Utilities. Overall Architecture. slcIoc Initialization. The saIocMain.cpp file - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Slc-aware Ioc

Diane Fairley11/11/2004

Slc-aware Ioc

SLC Executive

Message Service

Page 2: Slc-aware Ioc

SLC Executive Slc-aware IOC Initialization

The SLC Executive Thread

Startup Process

Shutdown Process

Some General Thread Issues

Utilities

Page 3: Slc-aware Ioc

Overall Architecture

Proxy

slcIoc

Alpha

slcExec

msgSend msgRecv

msgHdlr

Slc Database

cstrAsync

bpmHdlr

mgntHdlr

mgntAsync

Epics database

Epics Land

dbSenddbRecv

dbHdlr

Msg service

DB service

Db Ctl Channel access

iocsh

Page 4: Slc-aware Ioc

slcIoc Initialization The saIocMain.cpp file

Epics initialization via st.cmd file Read environment variables

slcIoc name (like the microname: XL01, XL02, … ) Proxy IP address (ip address of PX01 for now)

Load epics databases Currently a Restart/Stop subroutine record

start cmlog client

iocInit()

slcStart()

iocsh(NULL)

Page 5: Slc-aware Ioc

slcStart()

Initializes slc globals

Starts the slcExec thread

Executes the Restart function

Page 6: Slc-aware Ioc

SLC Globals

discovered_name Name string, from environment variable

proxy_ip_address from environment variable The ip address string in xxx.xxx.xxx.xxx format

Db downloadEvent semaphore

Name Type Represents

pName char * Name of thread

tid epicsThreadId Thread identifier

active epicsBoolean True if thread is active / looping; set by thread

stop epicsBoolean True if thread should stop; set by slcExec

mqId epicsMessageQueueId Message queue identifier

Cmlog_client_h long cmlog client handle

• slcThreads[ thread enum]– Array of thread information and global resources

saIocJobs[jobcode] = thread enum converts micro job code to an slcIoc thread

enumeration

slcSockets[ socket enum] Array of socket descriptors

dbExists

Page 7: Slc-aware Ioc

The SLC Executive Thread

Manages the slc startup, creating all other slc threads in order

Supervises threads and globals

Manages a clean shutdown of slc threads

Responds to slcRestart (IPL a micro)

Responds to slcStop (RESET a micro)

SlcExec thread initialization slcCmlogOpen Create a message queue Set slcExec global active=True Go into loop waiting for messages

Page 8: Slc-aware Ioc

slcRestart Commanded via IPL on VMS control system

TST_SLC_NOTIFY message “BOOT” Received by msgRecv, forwarded to msgHdlr

Commanded from ioc shell >slcRestart

Commanded from channel access via subroutine record Sets CSTR:<micro>:1:REST.A=0, EDM display can set this

Commanded from slcStart() initialization

Page 9: Slc-aware Ioc

SLC Restart

slcIoc

Epics

slcExec

Restart SubRecord

Epics database

Msg service

DB service

Db CtlChannel access

iocsh

Initialization

Page 10: Slc-aware Ioc

slcRestart

Send TEST_START message to slcExec From msgHdlr, or from slcRestart iocsh command, or from subRecord

slcExec process: Phase I If threads are running, call slcStop

Wait for all threads to stop

Create downloadEvent semaphore for threads to wait on

Create all threads except msgRecv, dbRecv threads

Wait for these threads to set their global active=True

Page 11: Slc-aware Ioc

Restart: Phase I

slcIoc

slcExec

msgSend

msgHdlr

cstrAsync

bpmHdlr

mgntHdlr

mgntAsync

Epics database

Epics Land

dbSend

dbHdlr

Msg service

DB service

Db CtlChannel access

Slc database

DownloadEvent

iocsh

Page 12: Slc-aware Ioc

slcRestart

Restart Phase II Create the msgRecv and dbRecv threads

Wait for the Recv threads to set their global active=True

Send a db_download_req message to dbSend message queue.

Goes back to its loop waiting for messages and checking on thread active flags

Page 13: Slc-aware Ioc

Restart: Phase II

slcIoc

slcExec

msgSend

msgHdlr

Slc Database

cstrAsync

bpmHdlr

mgntHdlr

mgntAsync

Epics database

Epics Land

dbSend

dbHdlr

Msg service

DB service

Db CtlChannel access

msgRecv dbRecv

Db download req

iocsh

Page 14: Slc-aware Ioc

slcRestart

Restart Phase III Database Service downloads the database

Database Service sets the dbExists flag to true

Database Service signals the downloadEvent semaphore to allow threads to proceed.

Page 15: Slc-aware Ioc

Ready to go

Proxy

slcIoc

Alpha

slcExec

msgSend msgRecv

msgHdlr

Slc Database

cstrAsync

bpmHdlr

mgntHdlr

mgntAsync

Epics database

Epics Land

dbSenddbRecv

dbHdlr

Msg service

DB service

Db CtlChannel access

iocsh

Page 16: Slc-aware Ioc

General Thread Initialization

slcCmlogOpen

Create resources Some will create a message queue Recv threads create a socket Async threads may create a timer Create any other thread specific resources

Set active=True

Perform dblists (optional) Wait on database event

Go into loop waiting for messages or wake-up

Page 17: Slc-aware Ioc

slcStop Commanded via RESET on VMS control

system TST_SLC_NOTIFY message “RSET” Received by msgRecv

Commanded from the ioc shell >slcStop

Commanded from channel access via subroutine record Sets CSTR:<micro>:1:REST.A = 1 EDM display can set this

Page 18: Slc-aware Ioc

slcStop Send TEST_STOP message to slcExec

From msgHdlr, or from iocsh command, or from subRecord

slcExec process Set all the thread global stop=True; Send TEST_STOP message to all threads with message

queues Wait for all thread global “active” flags to be set false Wait for all threads to stop Delete the global db downloadEvent Set dbExists to false; Set all thread global “stop” flags back to False; Could re-initialize all globals, do final global resource

cleanup…. go back to loop waiting for messages

Page 19: Slc-aware Ioc

General Thread Shutdown Release resources

msg queues, sockets, heap memory, timers, semaphores

slcCmlogClose()

set active=False

Set tid=NO_THREAD

Return

Page 20: Slc-aware Ioc

General slcIoc thread assumptions There are three basic thread types

‘socket’ threads that wait at sockets ‘message queue’ threads that wait at queues Async threads that wake up periodically

Non-message queue threads must poll the stop flag! No ‘kill a thread’ function in epics thread library Allows for orderly clean-up in all threads at all times ‘waits’ should have a timeout Possibly, message queue threads may wait indefinitely at

the queue because they can receive a TEST_STOP message.

Sockets should be non-blocking or interruptable

Page 21: Slc-aware Ioc

Some Utilities Thread Utilities

slcThreadNameEnum getThreadEnum(epicsThreadId tid); slcThreadNameEnum getThreadEnumByName(const char* name); char* getMicroname(void); eg: ‘XL02’ char* getProxyIPString(void); eg: ‘142.67.94.25’ some new wait(…) utilities

To be used by threads when waiting (with a timeout) on a flag or socket or ….

slcCmlog Utilities int slcCmlogOpen(void); int slcCmlogClose(void); int slcCmlogLogMsg (…,.,..,…., ...);

Message queue utilities epicsMessageQueueId createMsgQ( slcThreadNameEnum thrd ); vmsstat_t sendToMsgQ ( slcThreadNameEnum thrd, void* msg, int size );

Page 22: Slc-aware Ioc

slcIoc Message Service Threads overview

Message structure

Some Assumptions

Message Flow

Utilities

Page 23: Slc-aware Ioc

Message Service

slcIoc

slcExec

msgSend msgRecv

msgHdlr

Slc Database

bpmHdlr

mgntHdlr

Epics database

Epics Land

Msg service

Channel access

Page 24: Slc-aware Ioc

Slc Message Service The msgRecv thread

“owns” the msg service socket; creates and destroys it Receives all incoming messages at the msg service socket Sends the incoming message to the proper slc Hdlr thread

Uses the slcIocJobs[job code] global

The msgSend thread Sends all outgoing message at the message service socket “uses” the message service socket When the connection fails, waits for the msgRecv thread to

re-connect. Checks for a valid socket in slcSockets[sdMsg]

The msgHdlr thread Handles messages with the TEST function code Handles the new TST_SLC_NOTIFY messages

Page 25: Slc-aware Ioc

Message StructureName Data type Represents

fwd_hdr_ts

ip_port_u

len

user

cmd

crc

ip_port_tu (int4u)

int4u

user_field_ts(int2u)

int1u

int1u

Lower half of the ip address, and the port number

Message bytecount minus this fwdheader

User defined; chunk count for large buffers;

Fwd_server command, e.g.

8 bit crc over header; currently set to 0x55

msgheader_ts

source[4]

dest[4]

timestamp[2]

func;

datalen;

char

char

int4u

int2u

int2u

Name of Alpha job that sent the message *

Name of destination micro *

VMS format timestamp

Function code (job code + function code)

Word count of the data in Reqdata

reqdata[] Array of int2u function-specific message data; packed; max size is NETVAXMSGLEN – sizeof(msgheader_ts)/2

NOTE: this structure is shared with VMS and micros

Page 26: Slc-aware Ioc

Message Service Assumptions Sockets are non-blocking or interruptable

They must be able to see the global thread stop flag

Large messages will need heap memory allocations Message queues do not (efficiently) allow variable size msgs Use a memory pool to avoid memory leaks, fragmentation

Messages from the VMS control system are little-endian, VMS format, and packed. The message service threads are responsible for converting

the header portions of the message

The other ‘job’ threads are responsible for converting the function specific portion of the message (reqdata)

Page 27: Slc-aware Ioc

Message Service message flow The msgRecv thread

Receives the message into a local inMsg variable using a getBuffer utility.

interprets the fwdheader Allocate memory to store a multi-packet message.

converts/unpacks the msgheader into native format

replaces timestamp in msgheader

Translates the incoming job code to an slcIoc thread id

sends the entire message on to the correct queue. Message queue send actually copies the message Large messages: reqdata portion would include a pointer

Page 28: Slc-aware Ioc

Message Service message flow The job thread

Reads the message into an inMsg variable. Ignores the fwdheader portion

Reads the message data length from the msgheader

converts/unpack the incoming function specific data Releases large message memory when it can, if necessary

uses the data – unidentified requirements here.

converts/packs the function specific reply into an outMsg variable.

Allocates memory for large response message

fills in the new msgheader. (leaves it in native format)

The outMsg reply is sent to the msgSend queue.

Page 29: Slc-aware Ioc

Message service message flow

The msgSend thread Reads the message into a msg variable

converts/packs the msgheader

fills in the fwdheader

sends reply to VMS control system Creates and sends multiple buffers for large messages De-allocates memory used by large messages

Page 30: Slc-aware Ioc

Converting and packing/unpacking Forward header and Msgheader

The forward header follows networking standard in VMS and micros – uses hton and ntoh

Jobs don’t need to see the forward header Conversion and unpacking handled in by Message Service

Function Specific Data (requests and replies) Typically a structure is defined for the data and shared by

the VMS, micros and slcIocs See nfs_ref/inc_c for xxx_reqreply_struc.*

To unpack, must memcpy data field-by-field from incoming msg.reqdata[] to a variable of this structure, then convert.

To pack, do the reverse, convert then memcpy field-by-field from structure to outgoing msg.reqdata[]

Utilities will be written for each shared structure.

Page 31: Slc-aware Ioc

Conversion Utilities void sswap(const unsigned short* s); void lswap(const unsigned long* l);

void swap_int2u(void* pOut2u, const void* pIn2u); void swap_int4u(void* pOut4u, const void* pIn4u);

void cvt_vms_to_ieee(void* pOutR4, const void* pInR4); void cvt_ieee_to_vms(void* pOutR4, const void* pInR4);

int getVMSTime(void* pDest); int epicsTimeToVMSTime(void* pDest, const

epicsTimeStamp* eTime);

long int diffVMSTimes_10usec(void* pRef, void* pLater); long int diffVMSTimes_10msec(void* pRef, void* pLater);

Page 32: Slc-aware Ioc

TCP Utilities SOCKET getConnection(unsigned short port, unsigned short socket);

Gets a connection with the proxy Registers with the proxy Reports error conditions

vmsstat_t getBuffer(SOCKET sd, fwd_hdr_ts *pFwd, void *pBuf, int bytesReqd, int *pBytesRcvd); Reads incoming message Allocates memory and re-creates full message from multi-packet Reports error conditions