Exemple #1
0
/**
 * proposer_sync - Send a sync command to all acceptors.
 *
 * For a sync to succeed, all acceptors need to tell us the instance number
 * of their last contiguous learn.  We take the minimum of these values
 * and then command everyone to truncate everything before this minimum.
 */
int
proposer_sync()
{
  int r;
  struct paxos_header hdr;
  struct yakyak yy;

  // If we haven't finished preparing as the proposer, don't sync.
  if (pax->prep != NULL) {
    return 1;
  }

  // If not everyone is live, we should delay syncing.
  if (pax->live_count != LIST_COUNT(&pax->alist)) {
    return 1;
  }

  // If our local last contiguous learn is the same as the previous sync
  // point, we don't need to sync.
  if (pax->ihole - 1 == pax->sync_prev) {
    return 0;
  }

  // If we're already syncing, increment the skip counter.
  if (pax->sync != NULL) {
    // Resync if we've waited too long for the sync to finish.
    if (++pax->sync->ps_skips < SYNC_SKIP_THRESH) {
      return 1;
    } else {
      g_free(pax->sync);
    }
  }

  // Create a new sync.
  pax->sync = g_malloc0(sizeof(*(pax->sync)));
  pax->sync->ps_total = LIST_COUNT(&pax->alist);
  pax->sync->ps_acks = 1;  // Including ourselves.
  pax->sync->ps_skips = 0;
  pax->sync->ps_last = 0;

  // Initialize a header.
  header_init(&hdr, OP_SYNC, ++pax->sync_id);

  // Pack and broadcast the sync.
  yakyak_init(&yy, 1);
  paxos_header_pack(&yy, &hdr);
  r = paxos_broadcast(&yy);
  yakyak_destroy(&yy);

  return r;
}
Exemple #2
0
/*******************************************************************************
 * apmmgr_event_trigger
 * 
 * This is the routine which is made available externally to the memory
 * partitioning module and performs initial event processing
*/
void apmmgr_event_trigger(apmmgr_attr_t *mpart, mempart_evttype_t evtype, ...)
{
	part_evtlist_t  *evt_list;
	va_list  ap;
	va_start(ap, evtype);

// kprintf("%s: mp = %p, evt = %d\n", __func__, mpart, evtype);

	/*
	 * it is possible that there is no apmmgr_attr_t yet even though there
	 * is an mempart_t (ie. mempart_t.resmgr_attr_p == NULL)
	*/
	if (mpart == NULL) return;

	switch (evtype)
	{
		case mempart_evttype_t_DELTA_INCR:
		case mempart_evttype_t_DELTA_DECR:
		{
			/*
			 * additional arguments:
			 * arg1 - current partition size
			 * arg2 - previous partition size (before the increment/decrement
			*/
			memsize_t  cur_size = va_arg(ap, memsize_t);
			memsize_t  prev_size = va_arg(ap, memsize_t);

			/*
			 * Since multiple events may be triggered from the DELTA_INCR/DECR,
			 * the check for registered events will be done in _apmmgr_event_trigger()
			*/
			_apmmgr_event_trigger(mpart, evtype, cur_size, prev_size);
			if (cur_size > prev_size) {
				_apmmgr_event_trigger(mpart, mempart_evttype_t_THRESHOLD_CROSS_OVER, cur_size, prev_size);
			} else if (cur_size < prev_size) {
				_apmmgr_event_trigger(mpart, mempart_evttype_t_THRESHOLD_CROSS_UNDER, cur_size, prev_size);
			}
#ifndef NDEBUG
			else crash();
#endif	/* NDEBUG */
			break;
		}

		case mempart_evttype_t_PROC_ASSOCIATE:
		case mempart_evttype_t_PROC_DISASSOCIATE:
		{
			/* check to see if there are any events of this type registered */
			evt_list = &mpart->event_list[MEMPART_EVTYPE_IDX(evtype)];
			if (LIST_COUNT(evt_list->active.list) > 0)
			{
				/*
				 * addition arguments:
				 * arg1 - pid_t of the associated/disassociated process
				*/
				pid_t  pid = va_arg(ap, pid_t);

#ifdef DISPLAY_EVENT_MSG
			kprintf("PROC_%sASSOCIATE: pid %d %s associated with mp %p (%s)\n",
						(evtype == mempart_evttype_t_PROC_DISASSOCIATE) ? "DIS" : "", pid,
						(evtype == mempart_evttype_t_PROC_DISASSOCIATE) ? "no longer" : "now",
						mpart, mpart->name);
#endif	/* DISPLAY_EVENT_MSG */

				/*
				 * for disassociation events, we optionally check whether a
				 * specific process id of interest has been provided
				*/
				if (evtype == mempart_evttype_t_PROC_DISASSOCIATE) {
					SEND_MP_EVENT(evt_list, (void *)&pid, pid_match);
				} else {
					SEND_MP_EVENT(evt_list, (void *)&pid, NULL);
				}
			}
			break;
		}

		case mempart_evttype_t_CONFIG_CHG_ATTR_MIN:
		{
			/* check to see if there are any events of this type registered */
			evt_list = &mpart->event_list[MEMPART_EVTYPE_IDX(evtype)];
			if (LIST_COUNT(evt_list->active.list) > 0)
			{
				/*
				 * addition arguments:
				 * arg1 - previous configuration (mempart_cfg_t *)
				 * arg2 - current configuration (mempart_cfg_t *)
				 * 
				 * From these args the 'cfg_chg.attr.min' will be built an sent
				 * to any registered processes
				*/
				mempart_cfg_t  *prev = va_arg(ap, mempart_cfg_t *);
				mempart_cfg_t  *cur = va_arg(ap, mempart_cfg_t *);

				if (cur->attr.size.min != prev->attr.size.min)
				{
#ifdef DISPLAY_EVENT_MSG
					kprintf("CONFIG_CHG_ATTR_MIN: mp %p (%s) from %P to %P\n",
							mpart, mpart->name, (paddr_t)prev->attr.size.min,
							(paddr_t)cur->attr.size.min);
#endif	/* DISPLAY_EVENT_MSG */
					SEND_MP_EVENT(evt_list, (void *)&cur->attr.size.min, NULL);
				}
			}
			break;
		}

		case mempart_evttype_t_CONFIG_CHG_ATTR_MAX:
		{
			/* check to see if there are any events of this type registered */
			evt_list = &mpart->event_list[MEMPART_EVTYPE_IDX(evtype)];
			if (LIST_COUNT(evt_list->active.list) > 0)
			{
				/*
				 * addition arguments:
				 * arg1 - previous configuration (mempart_cfg_t *)
				 * arg2 - current configuration (mempart_cfg_t *)
				 * 
				 * From these args the 'cfg_chg.attr.max' will be built an sent
				 * to any registered processes
				*/
				mempart_cfg_t  *prev = va_arg(ap, mempart_cfg_t *);
				mempart_cfg_t  *cur = va_arg(ap, mempart_cfg_t *);

				if (cur->attr.size.max != prev->attr.size.max)
				{
#ifdef DISPLAY_EVENT_MSG
					kprintf("CONFIG_CHG_ATTR_MAX: mp %p (%s) from %P to %P\n",
							mpart, mpart->name, (paddr_t)prev->attr.size.max,
							(paddr_t)cur->attr.size.max);
#endif	/* DISPLAY_EVENT_MSG */
					SEND_MP_EVENT(evt_list, (void *)&cur->attr.size.max, NULL);
				}
			}
			break;
		}
Exemple #3
0
/*
 * __apmmgr_event_trigger2
 * 
 * This routine will handle all of the possible memory class DELTA and
 * THRESHOLD_CROSS events. It is only called from _apmmgr_event_trigger2()
*/
static INLINE void __apmmgr_event_trigger2(apmmgr_attr_t *mpart, memclass_evttype_t evtype,
										memsize_t cur_size, memsize_t prev_size)
{
	part_evtlist_t  *evt_list;

	/* check to see if there are any events of this type registered */
	evt_list = &mpart->event_list[MEMCLASS_EVTYPE_IDX(evtype)];
	if (LIST_COUNT(evt_list->active.list) == 0) return;

	switch (evtype)
	{
		/* handle all the deltas */
		case memclass_evttype_t_DELTA_TF_INCR:
		case memclass_evttype_t_DELTA_TF_DECR:
		case memclass_evttype_t_DELTA_RF_INCR:
		case memclass_evttype_t_DELTA_RF_DECR:
		case memclass_evttype_t_DELTA_UF_INCR:
		case memclass_evttype_t_DELTA_UF_DECR:
		case memclass_evttype_t_DELTA_TU_INCR:
		case memclass_evttype_t_DELTA_TU_DECR:
		case memclass_evttype_t_DELTA_RU_INCR:
		case memclass_evttype_t_DELTA_RU_DECR:
		case memclass_evttype_t_DELTA_UU_INCR:
		case memclass_evttype_t_DELTA_UU_DECR:
		{

#ifdef DISPLAY_EVENT_MSG
			kprintf("%s: mp %p (%s) from %P to %P\n", mclass_evt_string(evtype),
					mpart, mpart->name, (paddr_t)prev_size, (paddr_t)cur_size);
#endif	/* DISPLAY_EVENT_MSG */

			if (cur_size > prev_size) {
				SEND_MC_DELTA_INCR_EVENTS(evt_list, cur_size, prev_size);
			} else if (cur_size < prev_size) {
				SEND_MC_DELTA_DECR_EVENTS(evt_list, cur_size, prev_size);
			}
#ifndef NDEBUG
			else crash();
#endif	/* NDEBUG */
			break;
		}

		case memclass_evttype_t_THRESHOLD_CROSS_TF_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_TF_UNDER:
		case memclass_evttype_t_THRESHOLD_CROSS_TU_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_TU_UNDER:
		case memclass_evttype_t_THRESHOLD_CROSS_RF_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_RF_UNDER:
		case memclass_evttype_t_THRESHOLD_CROSS_UF_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_UF_UNDER:
		case memclass_evttype_t_THRESHOLD_CROSS_RU_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_RU_UNDER:
		case memclass_evttype_t_THRESHOLD_CROSS_UU_OVER:
		case memclass_evttype_t_THRESHOLD_CROSS_UU_UNDER:
		{

#ifdef DISPLAY_EVENT_MSG
			kprintf("%s: mp %p (%s) from %P to %P\n", mclass_evt_string(evtype),
					mpart, mpart->name, (paddr_t)prev_size, (paddr_t)cur_size);
#endif	/* DISPLAY_EVENT_MSG */

			if (cur_size > prev_size) {
				SEND_MC_THRESHOLD_X_OVER_EVENTS(evt_list, cur_size, prev_size);
			} else if (cur_size < prev_size) {
				SEND_MC_THRESHOLD_X_UNDER_EVENTS(evt_list, cur_size, prev_size);
			}
#ifndef NDEBUG
			else crash();
#endif	/* NDEBUG */
			break;
		}

		default:
#ifdef DISPLAY_EVENT_MSG
			kprintf("Unknown event: %d\n", evtype);
#endif	/* DISPLAY_EVENT_MSG */
			break;
	}
}
Exemple #4
0
/*
 * _apmmgr_event_trigger
 * 
 * This is the routine which is made available externally to the memory
 * partitioning module and performs initial event processing
*/
static void _apmmgr_event_trigger(apmmgr_attr_t *mpart, memclass_evttype_t evtype,
										memsize_t cur_size, memsize_t prev_size)
{
	part_evtlist_t  *evt_list;

	/*
	 * it is possible that there is no apmmgr_attr_t yet even though there
	 * is an mempart_t (ie. mempart_t.resmgr_attr_p == NULL)
	*/
	if (mpart == NULL)
		return;

	/* check to see if there are any events of this type registered */
	evt_list = &mpart->event_list[MEMPART_EVTYPE_IDX(evtype)];
	if (LIST_COUNT(evt_list->active.list) == 0) return;

	switch (evtype)
	{
		case mempart_evttype_t_THRESHOLD_CROSS_OVER:
		case mempart_evttype_t_THRESHOLD_CROSS_UNDER:
		{
#ifdef DISPLAY_EVENT_MSG
			kprintf("THRESHOLD_CROSS %s: mp %p (%s) from %P to %P\n",
					(cur_size > prev_size) ? "over" : ((cur_size < prev_size) ? "under" : "?"),
					mpart, mpart->name, (paddr_t)prev_size, (paddr_t)cur_size);
#endif	/* DISPLAY_EVENT_MSG */
			if (cur_size > prev_size) {
				SEND_MP_THRESHOLD_X_OVER_EVENTS(evt_list, cur_size, prev_size);
			} else if (cur_size < prev_size) {
				SEND_MP_THRESHOLD_X_UNDER_EVENTS(evt_list, cur_size, prev_size);
			}
#ifndef NDEBUG
			else crash();
#endif	/* NDEBUG */
			break;
		}

		case mempart_evttype_t_DELTA_INCR:
		case mempart_evttype_t_DELTA_DECR:
		{
#ifdef DISPLAY_EVENT_MSG
			kprintf("DELTA %s: mp %p (%s) from %P to %P\n",
					(cur_size > prev_size) ? "incr" : ((cur_size < prev_size) ? "decr" : "?"),
					mpart, mpart->name, (paddr_t)prev_size, (paddr_t)cur_size);
#endif	/* DISPLAY_EVENT_MSG */
			if (cur_size > prev_size) {
				SEND_MP_DELTA_INCR_EVENTS(evt_list, cur_size, prev_size);
			} else if (cur_size < prev_size) {
				SEND_MP_DELTA_DECR_EVENTS(evt_list, cur_size, prev_size);
			}
#ifndef NDEBUG
			else crash();
#endif	/* NDEBUG */
			break;
		}

		default:
#ifdef DISPLAY_EVENT_MSG
			kprintf("Unknown event: %d\n", evtype);
#endif	/* DISPLAY_EVENT_MSG */
			break;
	}
}