96f640a762
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.
106 строки
2.9 KiB
C
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;
|
|
}
|