Midas Buffer Manager Functions (bm_xxx)
[The midas.h & midas.c]


Functions

INT bm_match_event (short int event_id, short int trigger_mask, EVENT_HEADER *pevent)
INT bm_open_buffer (char *buffer_name, INT buffer_size, INT *buffer_handle)
INT bm_close_buffer (INT buffer_handle)
INT bm_close_all_buffers (void)
INT bm_set_cache_size (INT buffer_handle, INT read_size, INT write_size)
INT bm_compose_event (EVENT_HEADER *event_header, short int event_id, short int trigger_mask, DWORD size, DWORD serial)
INT bm_request_event (HNDLE buffer_handle, short int event_id, short int trigger_mask, INT sampling_type, HNDLE *request_id, void(*func)(HNDLE, HNDLE, EVENT_HEADER *, void *))
INT bm_remove_event_request (INT buffer_handle, INT request_id)
INT bm_delete_request (INT request_id)
INT bm_send_event (INT buffer_handle, void *source, INT buf_size, INT async_flag)
INT bm_flush_cache (INT buffer_handle, INT async_flag)
INT bm_receive_event (INT buffer_handle, void *destination, INT *buf_size, INT async_flag)
INT bm_skip_event (INT buffer_handle)
INT bm_push_event (char *buffer_name)
INT bm_check_buffers ()
INT bm_empty_buffers ()


Function Documentation

INT bm_check_buffers  ) 
 

Check if any requested event is waiting in a buffer

Returns:
TRUE More events are waiting
FALSE No more events are waiting

Definition at line 6817 of file midas.c.

Referenced by cm_yield().

INT bm_close_all_buffers void   ) 
 

Close all open buffers

Returns:
BM_SUCCESS

Definition at line 4105 of file midas.c.

Referenced by cm_disconnect_experiment(), and cm_set_client_info().

INT bm_close_buffer INT  buffer_handle  ) 
 

Closes an event buffer previously opened with bm_open_buffer().

Parameters:
buffer_handle buffer handle
Returns:
BM_SUCCESS, BM_INVALID_HANDLE

Definition at line 3994 of file midas.c.

Referenced by bm_close_all_buffers(), and source_unbooking().

INT bm_compose_event EVENT_HEADER event_header,
short int  event_id,
short int  trigger_mask,
DWORD  size,
DWORD  serial
 

Compose a Midas event header. An event header can usually be set-up manually or through this routine. If the data size of the event is not known when the header is composed, it can be set later with event_header->data-size = <...> Following structure is created at the beginning of an event

typedef struct {
 short int     event_id;
 short int     trigger_mask;
 DWORD         serial_number;
 DWORD         time_stamp;
 DWORD         data_size;
} EVENT_HEADER;

char event[1000];
 bm_compose_event((EVENT_HEADER *)event, 1, 0, 100, 1);
 *(event+sizeof(EVENT_HEADER)) = <...>
Parameters:
event_header pointer to the event header
event_id event ID of the event
trigger_mask trigger mask of the event
size size if the data part of the event in bytes
serial serial number
Returns:
BM_SUCCESS

Definition at line 5080 of file midas.c.

Referenced by cm_msg(), cm_msg1(), and source_scan().

INT bm_delete_request INT  request_id  ) 
 

Deletes an event request previously done with bm_request_event(). When an event request gets deleted, events of that requested type are not received any more. When a buffer is closed via bm_close_buffer(), all event requests from that buffer are deleted automatically

Parameters:
request_id request identifier given by bm_request_event()
Returns:
BM_SUCCESS, BM_INVALID_HANDLE

Definition at line 5387 of file midas.c.

Referenced by bm_close_buffer(), and source_unbooking().

INT bm_empty_buffers  ) 
 

Clears event buffer and cache. If an event buffer is large and a consumer is slow in analyzing events, events are usually received some time after they are produced. This effect is even more experienced if a read cache is used (via bm_set_cache_size()). When changes to the hardware are made in the experience, the consumer will then still analyze old events before any new event which reflects the hardware change. Users can be fooled by looking at histograms which reflect the hardware change many seconds after they have been made.

To overcome this potential problem, the analyzer can call bm_empty_buffers() just after the hardware change has been made which skips all old events contained in event buffers and read caches. Technically this is done by forwarding the read pointer of the client. No events are really deleted, they are still visible to other clients like the logger.

Note that the front-end also contains write buffers which can delay the delivery of events. The standard front-end framework mfe.c reduces this effect by flushing all buffers once every second.

Returns:
BM_SUCCESS

Definition at line 7139 of file midas.c.

Referenced by handFlush(), source_booking(), and source_unbooking().

INT bm_flush_cache INT  buffer_handle,
INT  async_flag
 

Empty write cache. This function should be used if events in the write cache should be visible to the consumers immediately. It should be called at the end of each run, otherwise events could be kept in the write buffer and will flow to the data of the next run.

Parameters:
buffer_handle Buffer handle obtained via bm_open_buffer()
async_flag Synchronous/asynchronous flag. If FALSE, the function blocks if the buffer has not enough free space to receive the full cache. If TRUE, the function returns immediately with a value of BM_ASYNC_RETURN without writing the cache.
Returns:
BM_SUCCESS, BM_INVALID_HANDLE
BM_ASYNC_RETURN Routine called with async_flag == TRUE and buffer has not enough space to receive cache
BM_NO_MEMORY Event is too large for network buffer or event buffer. One has to increase MAX_EVENT_SIZE or EVENT_BUFFER_SIZE in midas.h and recompile.

Definition at line 5803 of file midas.c.

Referenced by bm_send_event(), close_buffers(), scan_fragment(), scheduler(), send_event(), and tr_stop().

INT bm_match_event short int  event_id,
short int  trigger_mask,
EVENT_HEADER pevent
 

Check if an event matches a given event request by the event id and trigger mask

Parameters:
event_id Event ID of request
trigger_mask Trigger mask of request
pevent Pointer to event to check
Returns:
TRUE if event matches request

Definition at line 3710 of file midas.c.

Referenced by bm_flush_cache(), bm_push_event(), bm_receive_event(), and bm_send_event().

INT bm_open_buffer char *  buffer_name,
INT  buffer_size,
INT *  buffer_handle
 

Open an event buffer. Two default buffers are created by the system. The "SYSTEM" buffer is used to exchange events and the "SYSMSG" buffer is used to exchange system messages. The name and size of the event buffers is defined in midas.h as EVENT_BUFFER_NAME and EVENT_BUFFER_SIZE. Following example opens the "SYSTEM" buffer, requests events with ID 1 and enters a main loop. Events are then received in process_event()

#include <stdio.h>
#include "midas.h"
void process_event(HNDLE hbuf, HNDLE request_id,
           EVENT_HEADER *pheader, void *pevent)
{
  printf("Received event #%d\r",
  pheader->serial_number);
}
main()
{
  INT status, request_id;
  HNDLE hbuf;
  status = cm_connect_experiment("pc810", "Sample", "Simple Analyzer", NULL);
  if (status != CM_SUCCESS)
  return 1;
  bm_open_buffer(EVENT_BUFFER_NAME, EVENT_BUFFER_SIZE, &hbuf);
  bm_request_event(hbuf, 1, TRIGGER_ALL, GET_ALL, request_id, process_event);

  do
  {
   status = cm_yield(1000);
  } while (status != RPC_SHUTDOWN && status != SS_ABORT);
  cm_disconnect_experiment();
  return 0;
}
Parameters:
buffer_name Name of buffer
buffer_size Size of buffer in bytes
buffer_handle Buffer handle returned by function
Returns:
BM_SUCCESS, BM_CREATED
BM_NO_SHM Shared memory cannot be created
BM_NO_MUTEX Mutex cannot be created
BM_NO_MEMORY Not enough memory to create buffer descriptor
BM_MEMSIZE_MISMATCH Buffer size conflicts with an existing buffer of different size
BM_INVALID_PARAM Invalid parameter

Definition at line 3772 of file midas.c.

Referenced by cm_msg(), cm_msg1(), cm_msg_register(), register_equipment(), and source_booking().

INT bm_push_event char *  buffer_name  ) 
 

Check a buffer if an event is available and call the dispatch function if found.

Parameters:
buffer_name Name of buffer
Returns:
BM_SUCCESS, BM_INVALID_HANDLE, BM_TRUNCATED, BM_ASYNC_RETURN, RPC_NET_ERROR

Definition at line 6545 of file midas.c.

Referenced by bm_check_buffers().

INT bm_receive_event INT  buffer_handle,
void *  destination,
INT *  buf_size,
INT  async_flag
 

Receives events directly. This function is an alternative way to receive events without a main loop.

It can be used in analysis systems which actively receive events, rather than using callbacks. A analysis package could for example contain its own command line interface. A command like "receive 1000 events" could make it necessary to call bm_receive_event() 1000 times in a row to receive these events and then return back to the command line prompt. The according bm_request_event() call contains NULL as the callback routine to indicate that bm_receive_event() is called to receive events.

#include <stdio.h>
#include "midas.h"
void process_event(EVENT_HEADER *pheader)
{
 printf("Received event #%d\r",
 pheader->serial_number);
}
main()
{
  INT status, request_id;
  HNDLE hbuf;
  char event_buffer[1000];
  status = cm_connect_experiment("", "Sample",
  "Simple Analyzer", NULL);
  if (status != CM_SUCCESS)
   return 1;
  bm_open_buffer(EVENT_BUFFER_NAME, EVENT_BUFFER_SIZE, &hbuf);
  bm_request_event(hbuf, 1, TRIGGER_ALL, GET_ALL, request_id, NULL);

  do
  {
   size = sizeof(event_buffer);
   status = bm_receive_event(hbuf, event_buffer, &size, ASYNC);
  if (status == CM_SUCCESS)
   process_event((EVENT_HEADER *) event_buffer);
   <...do something else...>
   status = cm_yield(0);
  } while (status != RPC_SHUTDOWN &&
  status != SS_ABORT);
  cm_disconnect_experiment();
  return 0;
}
Parameters:
buffer_handle buffer handle
destination destination address where event is written to
buf_size size of destination buffer on input, size of event plus header on return.
async_flag Synchronous/asynchronous flag. If FALSE, the function blocks if no event is available. If TRUE, the function returns immediately with a value of BM_ASYNC_RETURN without receiving any event.
Returns:
BM_SUCCESS, BM_INVALID_HANDLE
BM_TRUNCATED The event is larger than the destination buffer and was therefore truncated
BM_ASYNC_RETURN No event available

Definition at line 6165 of file midas.c.

Referenced by handFlush(), and source_scan().

INT bm_remove_event_request INT  buffer_handle,
INT  request_id
 

Delete a previously placed request for a specific event type in the client structure of the buffer refereced by buffer_handle.

Parameters:
buffer_handle Handle to the buffer where the re- quest should be placed in
request_id Request id returned by bm_request_event
Returns:
BM_SUCCESS, BM_INVALID_HANDLE, BM_NOT_FOUND, RPC_NET_ERROR

Definition at line 5314 of file midas.c.

Referenced by bm_delete_request().

INT bm_request_event HNDLE  buffer_handle,
short int  event_id,
short int  trigger_mask,
INT  sampling_type,
HNDLE *  request_id,
void(*)(HNDLE, HNDLE, EVENT_HEADER *, void *)  func
 

Place an event request based on certain characteristics. Multiple event requests can be placed for each buffer, which are later identified by their request ID. They can contain different callback routines. Example see bm_open_buffer() and bm_receive_event()

Parameters:
buffer_handle buffer handle obtained via bm_open_buffer()
event_id event ID for requested events. Use EVENTID_ALL to receive events with any ID.
trigger_mask trigger mask for requested events. The requested events must have at least one bit in its trigger mask common with the requested trigger mask. Use TRIGGER_ALL to receive events with any trigger mask.
sampling_type specifies how many events to receive. A value of GET_ALL receives all events which match the specified event ID and trigger mask. If the events are consumed slower than produced, the producer is automatically slowed down. A value of GET_SOME receives as much events as possible without slowing down the producer. GET_ALL is typically used by the logger, while GET_SOME is typically used by analyzers.
request_id request ID returned by the function. This ID is passed to the callback routine and must be used in the bm_delete_request() routine.
func allback routine which gets called when an event of the specified type is received.
Returns:
BM_SUCCESS, BM_INVALID_HANDLE
BM_NO_MEMORY too many requests. The value MAX_EVENT_REQUESTS in midas.h should be increased.

Definition at line 5246 of file midas.c.

Referenced by cm_msg_register(), and source_booking().

INT bm_send_event INT  buffer_handle,
void *  source,
INT  buf_size,
INT  async_flag
 

Sends an event to a buffer. This function check if the buffer has enough space for the event, then copies the event to the buffer in shared memory. If clients have requests for the event, they are notified via an UDP packet.

char event[1000];
// create event with ID 1, trigger mask 0, size 100 bytes and serial number 1
bm_compose_event((EVENT_HEADER *) event, 1, 0, 100, 1);

// set first byte of event
*(event+sizeof(EVENT_HEADER)) = <...>
#include <stdio.h>
#include "midas.h"
main()
{
 INT status, i;
 HNDLE hbuf;
 char event[1000];
 status = cm_connect_experiment("", "Sample", "Producer", NULL);
 if (status != CM_SUCCESS)
 return 1;
 bm_open_buffer(EVENT_BUFFER_NAME, EVENT_BUFFER_SIZE, &hbuf);

 // create event with ID 1, trigger mask 0, size 100 bytes and serial number 1
 bm_compose_event((EVENT_HEADER *) event, 1, 0, 100, 1);

 // set event data
 for (i=0 ; i<100 ; i++)
 *(event+sizeof(EVENT_HEADER)+i) = i;
 // send event
 bm_send_event(hbuf, event, 100+sizeof(EVENT_HEADER), SYNC);
 cm_disconnect_experiment();
 return 0;
}
Parameters:
buffer_handle Buffer handle obtained via bm_open_buffer()
source Address of event buffer
buf_size Size of event including event header in bytes
async_flag Synchronous/asynchronous flag. If FALSE, the function blocks if the buffer has not enough free space to receive the event. If TRUE, the function returns immediately with a value of BM_ASYNC_RETURN without writing the event to the buffer
Returns:
BM_SUCCESS, BM_INVALID_HANDLE, BM_INVALID_PARAM
BM_ASYNC_RETURN Routine called with async_flag == TRUE and buffer has not enough space to receive event
BM_NO_MEMORY Event is too large for network buffer or event buffer. One has to increase MAX_EVENT_SIZE or EVENT_BUFFER_SIZE in midas.h and recompile.

Definition at line 5451 of file midas.c.

Referenced by cm_msg(), cm_msg1(), rpc_send_event(), and send_event().

INT bm_set_cache_size INT  buffer_handle,
INT  read_size,
INT  write_size
 

Modifies buffer cache size. Without a buffer cache, events are copied to/from the shared memory event by event.

To protect processed from accessing the shared memory simultaneously, semaphores are used. Since semaphore operations are CPU consuming (typically 50-100us) this can slow down the data transfer especially for small events. By using a cache the number of semaphore operations is reduced dramatically. Instead writing directly to the shared memory, the events are copied to a local cache buffer. When this buffer is full, it is copied to the shared memory in one operation. The same technique can be used when receiving events.

The drawback of this method is that the events have to be copied twice, once to the cache and once from the cache to the shared memory. Therefore it can happen that the usage of a cache even slows down data throughput on a given environment (computer type, OS type, event size). The cache size has therefore be optimized manually to maximize data throughput.

Parameters:
buffer_handle buffer handle obtained via bm_open_buffer()
read_size cache size for reading events in bytes, zero for no cache
write_size cache size for writing events in bytes, zero for no cache
Returns:
BM_SUCCESS, BM_INVALID_HANDLE, BM_NO_MEMORY, BM_INVALID_PARAM

Definition at line 4983 of file midas.c.

Referenced by register_equipment().

INT bm_skip_event INT  buffer_handle  ) 
 

Skip all events in current buffer.

Useful for single event displays to see the newest events

Parameters:
buffer_handle Handle of the buffer. Must be obtained via bm_open_buffer.
Returns:
BM_SUCCESS, BM_INVALID_HANDLE, RPC_NET_ERROR

Definition at line 6497 of file midas.c.


Midas DOC Version 1.9.5 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk