1
1
openmpi/orte/test/system/opal_hotel.c
Jeff Squyres 96f640a762 Add new "opal_hotel" class. Abstractly speaking, this class does the
following:

 * Provides a fixed number of resource slots (i.e., "hotel rooms").
 * Allows one thing to occupy a resource slot at a time (i.e., each
   hotel room can have an occupant check in to that room).
 * Resource slots can be vacated at any time (i.e., occupants can
   voluntarily check out of their hotel room).
 * Resource slots can be occupied for a specific maximum amount of
   time.  If that time expires, the occupant is forcibly evicted and
   the upper layer is notified via (libevent) callback (i.e., the maid
   will kick an occupant of out of their room when their reservation
   is over).

This class can be to be used for things like retransmission schemes
for unreliable transports.  For example, a message sent on an
unreliable transport can be checked in to a hotel room.  If an ACK for
that message is received, the message can be checked out.  But if the
ACK is never received, the message will eventually be evicted from its
room and the upper layer will be notified that the message failed to
check out in time (i.e., that an ACK for that message was not received
in time).

Code using this class is currently being developed off-trunk, but will
be coming to SVN soon.

This commit was SVN r27067.
2012-08-16 17:29:55 +00:00

106 строки
2.9 KiB
C

/* -*- C -*-
*
* $HEADER$
*
*/
#include <stdio.h>
#include <unistd.h>
#include "opal/mca/event/event.h"
#include "opal/class/opal_hotel.h"
#include "opal/runtime/opal.h"
#include "opal/runtime/opal_progress.h"
#define NUM_OCC 200
#define NUM_RMS 128
#define NUM_CYCLES 10
static int num_evicted = 0;
typedef struct {
int id;
int room;
} occupant_t;
occupant_t occupants[NUM_OCC];
occupant_t *checked_out[NUM_OCC];
static void evict_cbfunc(opal_hotel_t *hotel,
int room_num,
void *occupant_arg)
{
int *occupant = (int*) occupant_arg;
fprintf(stderr, "Room %d / occupant %d evicted!\n", *occupant, room_num);
++num_evicted;
}
int main(int argc, char* argv[])
{
int rc;
opal_hotel_t hotel;
int i, j, rm;
int num_occupied;
if (0 > (rc = opal_init(&argc, &argv))) {
fprintf(stderr, "orte_hotel: couldn't init opal - error code %d\n", rc);
return rc;
}
OBJ_CONSTRUCT(&hotel, opal_hotel_t);
opal_hotel_init(&hotel, NUM_RMS, 3000000, OPAL_EV_SYS_HI_PRI, evict_cbfunc);
/* prep the occupants */
for (i=0; i < NUM_OCC; i++) {
occupants[i].id = i;
occupants[i].room = -1;
}
/* arbitrarily checkin/checkout some things */
for (i=0; i < NUM_RMS; i++) {
if (OPAL_SUCCESS != opal_hotel_checkin(&hotel,
(void*)(&occupants[i]), &rm)) {
fprintf(stderr, "Hotel is fully occupied\n");
continue;
}
occupants[i].room = rm;
fprintf(stderr, "Occupant %d checked into room %d\n",
occupants[i].id, rm);
}
num_occupied = NUM_RMS;
fprintf(stderr, "---------------------------------------\n");
/* cycle thru adding and removing some */
for (i=0; i < NUM_CYCLES; i++) {
for (j=0; j < 30; j++) {
fprintf(stderr, "Checking occupant %d out of room %d\n",
occupants[i + j].id, occupants[i + j].room);
opal_hotel_checkout(&hotel, occupants[i + j].room);
--num_occupied;
}
for (j=0; j < 30; j++) {
if (OPAL_SUCCESS !=
opal_hotel_checkin(&hotel, (void*) &(occupants[i + j]), &rm)) {
fprintf(stderr, "Hotel is fully occupied\n");
continue;
}
occupants[i + j].room = rm;
fprintf(stderr, "Occupant %d checked into room %d\n",
occupants[i + j].id, rm);
++num_occupied;
}
fprintf(stderr, "---------------------------------------\n");
}
/* sit here and see if we get an eviction notice */
fprintf(stderr, "Waiting for %d evictions...\n", num_occupied);
while (num_evicted < num_occupied) {
opal_progress();
}
fprintf(stderr, "All occupants evicted!\n");
OBJ_DESTRUCT(&hotel);
opal_finalize();
return 0;
}