예제 #1
0
파일: control.c 프로젝트: eldesh/smlsharp
static void
activate(struct sml_control *control)
{
	unsigned int old;

	/* lock; all updates so far must be acquired */
	old = fetch_and(acquire, &control->state, ~INACTIVE_FLAG);
	if (IS_ACTIVE(old)) {
		mutex_lock(&control->inactive_wait_lock);
		pthread_cleanup_push(cleanup_mutex_unlock,
				     &control->inactive_wait_lock);
		while ((old = fetch_and(acquire, &control->state,
					~INACTIVE_FLAG),
			IS_ACTIVE(old)))
			cond_wait(&control->inactive_wait_cond,
				  &control->inactive_wait_lock);
		pthread_cleanup_pop(1);
	}

	assert(IS_ACTIVE(load_relaxed(&control->state)));
}
예제 #2
0
QVariant DynamicPlaylists::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) {
        return RulesPlaylists::data(index, role);
    }

    if (index.parent().isValid() || index.row()>=entryList.count()) {
        return QVariant();
    }

    switch (role) {
    case Qt::DecorationRole:
        return IS_ACTIVE(entryList.at(index.row()).name) ? Icons::self()->replacePlayQueueIcon : icn;
    case Cantata::Role_Actions: {
        QVariant v;
        v.setValue<QList<Action *> >(QList<Action *>() << (IS_ACTIVE(entryList.at(index.row()).name) ? stopAction : startAction));
        return v;
    }
    default:
        return RulesPlaylists::data(index, role);
    }
}
예제 #3
0
파일: usb_mac.c 프로젝트: julianliaw/ckb
int _usbinput(usbdevice* kb, uchar* message, const char* file, int line){
    if(!IS_ACTIVE(kb))
        return -1;
    CFIndex length = MSG_SIZE;
    IOReturn res = IOHIDDeviceGetReport(kb->handle, kIOHIDReportTypeFeature, 0, message, &length);
    if(res != kIOReturnSuccess){
        printf("Error: usbinput (%s:%d): Got return value %d\n", file, line, res);
        return 0;
    }
    if(length != MSG_SIZE)
        printf("Warning: usbinput (%s:%d): Read %d bytes (expected %d)\n", file, line, (int)length, MSG_SIZE);
    return length;
}
예제 #4
0
void G_AdjustClientPositions(gentity_t *ent, int time, qboolean forward) {
	int i;
	gentity_t *list;

	for (i = 0; i < level.numConnectedClients; i++) {
		list = g_entities + level.sortedClients[i];

		if (list != ent && IS_ACTIVE(list)) {
			if (forward) {
				G_AdjustSingleClientPosition(list, time);
			} else {G_ReAdjustSingleClientPosition(list);}
		}
	}
}
예제 #5
0
/*
 * restituisce un puntatore ad un publication record preallocato
 * se tutti i P_RECORD_PER_CPU sono utilizzati si attende l'evasione di una
 * richiesta che liberi un publication record
 */
static pub_record *get_pub_record(fc_dl_skiplist_t *p, int cpu){
	pub_record **array = p->p_record_array[cpu];
	int idx = p->p_record_idx[cpu];

	while(1){
		if(!IS_ACTIVE(array[idx])){
			ACTIVATE(array[idx]);
			p->p_record_idx[cpu] = (p->p_record_idx[cpu] + 1) % P_RECORD_PER_CPU;
			return array[idx];
		}
		/* nessun publication record libero: tento di diventare un combiner */
		fc_dl_sl_wait_response(p);
	}
}
예제 #6
0
파일: control.c 프로젝트: eldesh/smlsharp
	/* unlock; all updates so far must be released */
	store_release(&control->state, INACTIVE(ASYNC));
	if (load_relaxed(&stop_the_world_flag)) {
		mutex_lock(&control->inactive_wait_lock);
		cond_signal(&control->inactive_wait_cond);
		mutex_unlock(&control->inactive_wait_lock);
	}
}

#else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */
static void
control_leave(struct sml_control *control)
{
	unsigned int old;

	assert(IS_ACTIVE(load_relaxed(&control->state)));
	/* progress even phase to odd phase */
	/* unlock; all updates so far must be released */
	old = fetch_or(release, &control->state, INACTIVE_FLAG | 1);

	if (old == ACTIVE(PRESYNC1))
		sync1_action();
	else if (old == ACTIVE(PRESYNC2))
		sync2_action(control);
}
예제 #7
0
#include "SDL.h"
#include "SDL_mixer.h"
#include "SDL_net.h"
#include "constants.h"
#include "main.h"
#include "input.h"
#include "sfx.h"
#include "misc.h"
#include "players.h"
#include "ai.h"
#include "terminal.h"
#include "world.h"
#include "net.h"
#include "packets.h"

struct Splayers players[NUM_PLAYERS];
int me;		/*	local player	*/
int recv_all_actions(int turn) {
    int i;
    struct action_node *action;

    for (i = 0; i < NUM_PLAYERS; i++) {
        if (IS_ACTIVE(i) && has_cities(i, 0)) {
            action = find_action(i, turn);
            if (!action || action->action == ACTION_NOTHING || (!server && !action->res_recv)) {
                if (!server || !players[i].ai)
                    return 0;
            }
        }
    }

    return 1;
}
예제 #8
0
int check_gameover(int world) {
    int i, num = 0;

    if (current_turn) {
        /* count alive players */
        for (i = 0; i < NUM_PLAYERS; i++) {
            if (IS_ACTIVE(i) && has_cities(i, world))
                num++;
        }

        if (num <= 1)
            return 1;
    }

    return 0;
}
예제 #9
0
/*----------------------------------------------------------------------+*/
void SPC_Conditional_Packet_Handler(void      * UNUSED_PARM(client_data),
				   int        * source,
				   SPCInputId * UNUSED_PARM(id))
/*----------------------------------------------------------------------+*/
{

  SPC_Channel_Ptr channel;
  
  channel = XeSPCHandleTerminator(*source);
  
  /* Okay, blast out of our wait */
  _DtSvcProcessLock();
  if( (channel==SPC_ERROR || !IS_ACTIVE(channel)) &&
      break_on_termination)
    SPC_XtBreak();
  _DtSvcProcessUnlock();
  /* return(TRUE); */
}
예제 #10
0
파일: control.c 프로젝트: eldesh/smlsharp
SML_PRIMITIVE void
sml_end()
{
	struct sml_control *control = tlv_get(current_control);

#ifndef WITHOUT_MULTITHREAD
	assert(IS_ACTIVE(load_relaxed(&control->state)));
#endif /* !WITHOUT_MULTITHREAD */
	assert(control->frame_stack->bottom == CALLER_FRAME_END_ADDRESS());

	control->frame_stack = control->frame_stack->next;

	if (control->frame_stack) {
		control_leave(control);
	} else {
		control_destroy(control);
	}
}
예제 #11
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Check if transaction must block.
 */
static inline int stm_check_quiesce(stm_tx_t *tx)
{
  stm_word_t s;

  /* Must be called upon start (while already active but before acquiring any lock) */
  assert(IS_ACTIVE(tx->status));

  ATOMIC_MB_FULL;
  if (ATOMIC_LOAD_ACQ(&quiesce) == 2) {
    s = ATOMIC_LOAD(&tx->status);
    SET_STATUS(tx->status, TX_IDLE);
    while (ATOMIC_LOAD_ACQ(&quiesce) == 2) {
      sched_yield();
    }
    SET_STATUS(tx->status, GET_STATUS(s));
    return 1;
  }
  return 0;
}
예제 #12
0
파일: spc-xt.c 프로젝트: idunham/cdesktop
/*-----------------------------------------------------------------------+*/
int SPC_Wait_For_Termination(SPC_Channel_Ptr channel)
/*-----------------------------------------------------------------------+*/
{
  int result;
  
  call_parent_method(channel, wait_for_termination, (channel), result);
  
  if(result==SPC_ERROR) return(SPC_ERROR);

  do {

    if(SPC_Select() == SPC_ERROR)
      return(SPC_ERROR);
    
  } while(IS_ACTIVE(channel));
  
  return(TRUE);
  
}
예제 #13
0
/* server decides if selected actions are successful or not */
void server_prepare_actions() {
    int i, mt;
    struct action_node *action, *action2;
    struct packet_result packet;

    for (i = 0; i < NUM_PLAYERS; i++) {
        if (IS_ACTIVE(i)) {
            action = find_action(i, current_turn);
            if (action) {
                switch (action->action) {
                case ACTION_PROPAGANDA:
                    action->success = randomize(1, 1);
                    action->res_num = randomize(1, 10);	/*	population number	*/
                    break;
                case ACTION_WARHEAD_10MT:
                case ACTION_WARHEAD_20MT:
                case ACTION_WARHEAD_50MT:
                case ACTION_WARHEAD_100MT:
                    mt = action->action - ACTION_WARHEAD_10MT;
                    /* check target for defense */
                    action2 = find_action(action->target_player, current_turn);
                    if (!action2)
                        do_error("server_prepare_actions()");	/*	shouldn't happen	*/
                    if (GET_MISSILE(i) > -1 && (action2->action == ACTION_LNDS || action2->action == ACTION_MEGA))
                        action->success = 0;
                    else if (GET_BOMBER(i) > -1 && action2->action == ACTION_MEGA)
                        action->success = 0;
                    else
                        action->success = 1;
                    action->res_num = randomize(damage[mt * 2], damage[(mt * 2) + 1]);	/*	damage	*/
                    break;
                }

                /* send result to other players */
                packet.turn = swap_int(current_turn);
                packet.player = swap_int(i);
                packet.success = swap_int(action->success);
                packet.res_num = swap_int(action->res_num);
                send_all_sockets(PACKET_RESULT, &packet, sizeof(struct packet_result));
            }
        }
    }
}
예제 #14
0
파일: devnode.c 프로젝트: TricksterGuy/ckb
void updateconnected(){
    char cpath[strlen(devpath) + 12];
    snprintf(cpath, sizeof(cpath), "%s0/connected", devpath);
    FILE* cfile = fopen(cpath, "w");
    if(!cfile){
        printf("Warning: Unable to update %s: %s\n", cpath, strerror(errno));
        return;
    }
    int written = 0;
    for(int i = 1; i < DEV_MAX; i++){
        if(IS_ACTIVE(keyboard + i)){
            written = 1;
            fprintf(cfile, "%s%d %s %s\n", devpath, i, keyboard[i].setting.serial, keyboard[i].name);
        }
    }
    if(!written)
        fputc('\n', cfile);
    fclose(cfile);
    chmod(cpath, S_READ);
}
예제 #15
0
파일: control.c 프로젝트: eldesh/smlsharp
	/* lock; all updates so far must be acquired */
	old = INACTIVE(ASYNC);
	if (cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC)))
		return;

	mutex_lock(&control->inactive_wait_lock);
	pthread_cleanup_push(cleanup_mutex_unlock,
			     &control->inactive_wait_lock);
	old = INACTIVE(ASYNC);
	while (!cmpswap_weak_acquire(&control->state, &old, ACTIVE(ASYNC))) {
		cond_wait(&control->inactive_wait_cond,
			  &control->inactive_wait_lock);
		old = INACTIVE(ASYNC);
	}
	pthread_cleanup_pop(1);
}

#else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */
static void
control_enter(struct sml_control *control)
{
	activate(control);
}

#endif /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */

SML_PRIMITIVE void
sml_leave()
{
	struct sml_control *control = tlv_get(current_control);
	assert(control->frame_stack->top == NULL);
	control->frame_stack->top = CALLER_FRAME_END_ADDRESS();
	control_leave(control);
}

SML_PRIMITIVE void
sml_enter()
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	assert(control->frame_stack->top == CALLER_FRAME_END_ADDRESS());
	control->frame_stack->top = NULL;
}

void *
sml_leave_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	old_frame_top = control->frame_stack->top;
	if (!old_frame_top)
		control->frame_stack->top = frame_pointer;
	control_leave(control);
	return old_frame_top;
}

void
sml_enter_internal(void *old_frame_top)
{
	struct sml_control *control = tlv_get(current_control);
	control_enter(control);
	control->frame_stack->top = old_frame_top;
}

#if defined WITHOUT_MULTITHREAD
void
sml_check_internal(void *frame_pointer ATTR_UNUSED)
{
}

#elif defined WITHOUT_CONCURRENCY
void
sml_check_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	void *old_frame_top;

	assert(load_relaxed(&control->state) == ACTIVE(ASYNC));
	if (load_relaxed(&stop_the_world_flag)) {
		old_frame_top = control->frame_stack->top;
		if (!old_frame_top)
			control->frame_stack->top = frame_pointer;
		store_release(&control->state, INACTIVE(SYNC1));
		mutex_lock(&control->inactive_wait_lock);
		cond_signal(&control->inactive_wait_cond);
		mutex_unlock(&control->inactive_wait_lock);
		control_enter(control);
		control->frame_stack->top = old_frame_top;
	}
}

#else /* !WITHOUT_MULTITHREAD && !WITHOUT_CONCURRENCY */
void
sml_check_internal(void *frame_pointer)
{
	struct sml_control *control = tlv_get(current_control);
	unsigned int state = load_relaxed(&control->state);
	void *old_frame_top;

	assert(IS_ACTIVE(state));

	if (state == ACTIVE(PRESYNC1)) {
		store_relaxed(&control->state, ACTIVE(SYNC1));
		sync1_action();
	} else if (state == ACTIVE(PRESYNC2)) {
		store_relaxed(&control->state, ACTIVE(SYNC2));
		old_frame_top = control->frame_stack->top;
		if (!old_frame_top)
			control->frame_stack->top = frame_pointer;
		sync2_action(control);
		control->frame_stack->top = old_frame_top;
	}
}
예제 #16
0
static int ppro_check_ctrs(unsigned int const cpu,
                           struct op_msrs const * const msrs,
                           struct cpu_user_regs const * const regs)
{
	u64 val;
	int i;
	int ovf = 0;
	unsigned long eip = regs->eip;
	int mode = xenoprofile_get_mode(current, regs);
	struct arch_msr_pair *msrs_content = vcpu_vpmu(current)->context;

	for (i = 0 ; i < num_counters; ++i) {
		if (!reset_value[i])
			continue;
		rdmsrl(msrs->counters[i].addr, val);
		if (CTR_OVERFLOWED(val)) {
			xenoprof_log_event(current, regs, eip, mode, i);
			wrmsrl(msrs->counters[i].addr, -reset_value[i]);
			if ( is_passive(current->domain) && (mode != 2) &&
				vpmu_is_set(vcpu_vpmu(current),
                                            VPMU_PASSIVE_DOMAIN_ALLOCATED) )
			{
				if ( IS_ACTIVE(msrs_content[i].control) )
				{
					msrs_content[i].counter = val;
					if ( IS_ENABLE(msrs_content[i].control) )
						ovf = 2;
				}
			}
			if ( !ovf )
				ovf = 1;
		}
	}

	/* Only P6 based Pentium M need to re-unmask the apic vector but it
	 * doesn't hurt other P6 variant */
	apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);

	return ovf;
}
예제 #17
0
static void
gst_net_time_provider_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstNetTimeProvider *self = GST_NET_TIME_PROVIDER (object);

  switch (prop_id) {
    case PROP_PORT:
      g_value_set_int (value, self->port);
      break;
    case PROP_ADDRESS:
      g_value_set_string (value, self->address);
      break;
    case PROP_CLOCK:
      g_value_set_object (value, self->clock);
      break;
    case PROP_ACTIVE:
      g_value_set_boolean (value, IS_ACTIVE (self));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
예제 #18
0
파일: usb_mac.c 프로젝트: julianliaw/ckb
void* krthread(void* context){
    while(1){
        // Max repeat speed: 1ms
        usleep(1000);
        int delay = keyrepeatdelay();
        if(delay <= 0)
            delay = 1;
        int interval = keyrepeatinterval();
        if(interval <= 0)
            interval = 1;
        for(int i = 1; i < DEV_MAX; i++){
            if(IS_ACTIVE(keyboard + i)){
                pthread_mutex_lock(&keyboard[i].keymutex);
                if(keyboard[i].lastkeypress != -1){
                    keyboard[i].keypresstime++;
                    if(keyboard[i].keypresstime >= delay && (keyboard[i].keypresstime - delay) % interval == 0)
                        keyretrigger(keyboard + i, keyboard[i].lastkeypress);
                }
                pthread_mutex_unlock(&keyboard[i].keymutex);
            }
        }
    }
    return 0;
}
예제 #19
0
void check_collisions()
{
	
	int i;
	int j;
	
	//remove bullets 
	for(i = 0; i < MAX_ACTOR; ++i)
	{
		actor* a = &actor_pool[i];
		if(!BOARD_inside(a->pos))
			ACTOR_kill(a);
	}

	// bullet vs enemies
	for(i = 0; i < MAX_ACTOR; ++i)
	{
		actor* a = &actor_pool[i];
		if(IS_ACTIVE(a) && 
		  (a->flags & F_BULLET) )
		{
			if( a->flags & F_COLLIDE_ENEMY)
			{
				for(j = 0; j < MAX_ACTOR; ++j)
				{
					actor* b = &actor_pool[j];				
					if(IS_ACTIVE(b) && !(b->flags & F_BULLET))
					{
						if(b->type ==  SHIP_FINAL_BOSS && game_state != INTER_LEVEL)
						{
								int c = final_boss_collide(b, a);
								//PART_damage(b->pos);
								if(c)
								{
									ACTOR_kill(a);
									pj_score += 30;
									if(c < 0)
									{
										pj_score += 10000;
										MENU_show();
										game_state = INTER_LEVEL;
										SOUND_play_song(0);
									}
								} 
						} else						// player bullets
						if(ACTOR_collide(b, a->pos))
						{
							if(b->type == POWER_UP && b->count > 15)
							{	
								ACTOR_kill(b);
								PART_explosion(b->pos);
								EFFECTS_small_explosion();
								pj_fire_count++;
								if(pj_fire_count >= 4)
								{
									pj_life += 0.11f;
								}
								pj_score += 100;
							}
							else if( b->type == SHIP_MEDIUM)
							{								
								if(rand01() < 0.01)
								{
									PART_explosion(b->pos, 5);
								} 
								else
								{
									PART_damage(b->pos, 1.0f);
								}
								b->life -= 0.1f; //3 bullets
								if(b->life < 0.0f)
								{
									vec3f v;									
									PART_explosion(b->pos);
									VMOV3(v, randf()*3.0f, randf()*3.0f,0.0f);									
									VADD(v, b->pos, v);
									PART_explosion(v);
									VMOV3(v, randf()*3.0f, randf()*3.0f,0.0f);									
									VADD(v, b->pos, v);
									PART_explosion(b->pos);
									ACTOR_kill(b);
									EFFECTS_medium_explosion();
								}
								pj_score += 300;
							}
							else if(b->type ==  SHIP_SMALL)
							{
								ACTOR_kill(b);
								PART_explosion(b->pos);
								EFFECTS_small_explosion();
								if(rand01() < 0.01f)
								{
									power_up_launch(b->pos);
								}
								pj_score += 100;
							}
							
							//kill bullet
							ACTOR_kill(a);
							
							//GARBAGE_explosion(a->pos);
						}
						// enemy bullets
						
					}
				}
			} 
			else if(a->flags & F_COLLIDE_PLAYER)
			{
				if(game_state == INTRO || game_state == DEAD) //hack
					return; 
				vec3f margin;
				VMOV3(margin, 1.5f, 3.0f, 1.0f);
				if(is_inside_2d(pj_pos, margin, a->pos))
				{
					pj_life -= 0.21f;
					PART_explosion(pj_pos);
					ACTOR_kill(a);

					if(pj_life < 0.0f)
					{
						MENU_show();
						game_state = DEAD;
					
					}
				}
			}
		}
	}

}
예제 #20
0
/* execute selected actions */
void do_actions() {
    int i, missile, bomber, i2;
    struct action_node *action;

    for (i = 0; i < NUM_PLAYERS; i++) {
        if (IS_ACTIVE(i)) {
            action = find_action(i, current_turn);
            if (action) {
                missile = -1;
                bomber = -1;
                switch (action->action) {
                case ACTION_BUILD:
                    if (has_cities(i, 0))
                        do_build(i);
                    break;
                case ACTION_PROPAGANDA:
                    if (has_cities(i, 0)) {
                        do_propaganda(i);
                        /* random message */
                        if (i == me && players[action->target_player].ai)
                            ai_random_message(action->target_player);
                    }
                    break;
                case ACTION_MISSILE_10MT:
                case ACTION_MISSILE_20MT:
                case ACTION_MISSILE_50MT:
                case ACTION_MISSILE_100MT:
                    if (has_cities(i, 0)) {
                        do_missile(i);
                        missile = action->action - ACTION_MISSILE_10MT;
                    }
                    break;
                case ACTION_WARHEAD_10MT:
                case ACTION_WARHEAD_20MT:
                case ACTION_WARHEAD_50MT:
                case ACTION_WARHEAD_100MT:
                    do_nuke(i);
                    if (!players[i].ai)
                        bomber = GET_BOMBER(i);	/*	don't unset so we can reuse the bomber	*/
                    else {
                        if (players[i].mt_left) {
                            /* check if the ai player has a warhead and enough capacity to reuse the bomber */
                            for (i2 = 0; i2 < 4; i2++) {
                                if (GET_STOCK(i, WEAPON_WARHEAD_10MT + i2) && megatons[i2] <= players[i].mt_left)
                                    bomber = GET_BOMBER(i);
                            }
                        }
                    }
                    /* random message */
                    if (i == me && players[action->target_player].ai && has_cities(me, 0))
                        ai_random_message(action->target_player);
                    break;
                case ACTION_NP1:
                case ACTION_GR2:
                    if (has_cities(i, 0)) {
                        do_bomber(i);
                        bomber = action->action - ACTION_NP1;
                    }
                    break;
                case ACTION_LNDS:
                case ACTION_MEGA:
                    if (has_cities(i, 0))
                        do_defense(i);
                    break;
                }

                GET_PREVIOUS(i) = action->action;	/*	remember action for next turn	*/
                GET_MISSILE(i) = missile;
                GET_BOMBER(i) = bomber;
            }
        }
    }
}
예제 #21
0
static gpointer
gst_net_time_provider_thread (gpointer data)
{
  GstNetTimeProvider *self = data;
  struct sockaddr_in tmpaddr;
  socklen_t len;
  GstNetTimePacket *packet;
  gint ret;

  while (TRUE) {
    GST_LOG_OBJECT (self, "doing select");
    ret = gst_poll_wait (self->priv->fdset, GST_CLOCK_TIME_NONE);
    GST_LOG_OBJECT (self, "select returned %d", ret);

    if (ret <= 0) {
      if (errno == EBUSY) {
        GST_LOG_OBJECT (self, "stop");
        goto stopped;
      } else if (errno != EAGAIN && errno != EINTR)
        goto select_error;
      else
        continue;
    } else {
      /* got data in */
      len = sizeof (struct sockaddr);

      packet = gst_net_time_packet_receive (self->priv->sock.fd,
          (struct sockaddr *) &tmpaddr, &len);

      if (!packet)
        goto receive_error;

      if (IS_ACTIVE (self)) {
        /* do what we were asked to and send the packet back */
        packet->remote_time = gst_clock_get_time (self->clock);

        /* ignore errors */
        gst_net_time_packet_send (packet, self->priv->sock.fd,
            (struct sockaddr *) &tmpaddr, len);
      }

      g_free (packet);

      continue;
    }

    g_assert_not_reached ();

    /* log errors and keep going */
  select_error:
    {
      GST_DEBUG_OBJECT (self, "select error %d: %s (%d)", ret,
          g_strerror (errno), errno);
      continue;
    }
  stopped:
    {
      GST_DEBUG_OBJECT (self, "shutting down");
      /* close socket */
      return NULL;
    }
  receive_error:
    {
      GST_DEBUG_OBJECT (self, "receive error");
      continue;
    }

    g_assert_not_reached ();

  }

  g_assert_not_reached ();

  return NULL;
}
예제 #22
0
파일: devnode.c 프로젝트: TricksterGuy/ckb
void readcmd(usbdevice* kb, const char* line){
    char word[strlen(line) + 1];
    int wordlen;
    // See if the first word is a serial number. If so, switch devices and skip to the next word.
    usbsetting* set = (IS_ACTIVE(kb) ? &kb->setting : 0);
    usbprofile* profile = (set ? &set->profile : 0);
    usbmode* mode = (profile ? profile->currentmode : 0);
    cmd command = NONE;
    cmdhandler handler = 0;
    int rgbchange = 0;
    // Read words from the input
    while(sscanf(line, "%s%n", word, &wordlen) == 1){
        line += wordlen;
        // Check for a command word
        if(!strcmp(word, "device")){
            command = DEVICE;
            handler = 0;
            continue;
        } else if(!strcmp(word, "mode")){
            command = MODE;
            handler = 0;
            continue;
        } else if(!strcmp(word, "switch")){
            command = NONE;
            handler = 0;
            if(profile)
                profile->currentmode = mode;
            rgbchange = 1;
            continue;
        } else if(!strcmp(word, "hwload")){
            command = NONE;
            handler = 0;
            if(profile)
                hwloadprofile(kb);
            rgbchange = 1;
        } else if(!strcmp(word, "hwsave")){
            command = NONE;
            handler = 0;
            if(profile)
                hwsaveprofile(kb);
        } else if(!strcmp(word, "erase")){
            command = NONE;
            handler = 0;
            if(mode)
                erasemode(mode);
            rgbchange = 1;
            continue;
        } else if(!strcmp(word, "eraseprofile")){
            command = NONE;
            handler = 0;
            if(profile){
                eraseprofile(profile);
                mode = profile->currentmode = getusbmode(0, profile);
            }
            rgbchange = 1;
            continue;
        } else if(!strcmp(word, "name")){
            command = NAME;
            handler = 0;
            if(mode)
                updatemod(&mode->id);
            continue;
        } else if(!strcmp(word, "profilename")){
            command = PROFILENAME;
            handler = 0;
            if(profile)
                updatemod(&profile->id);
            continue;
        } else if(!strcmp(word, "bind")){
            command = BIND;
            handler = cmd_bind;
            continue;
        } else if(!strcmp(word, "unbind")){
            command = UNBIND;
            handler = cmd_unbind;
            continue;
        } else if(!strcmp(word, "rebind")){
            command = REBIND;
            handler = cmd_rebind;
            continue;
        } else if(!strcmp(word, "macro")){
            command = MACRO;
            handler = 0;
            continue;
        } else if(!strcmp(word, "rgb")){
            command = RGB;
            handler = cmd_ledrgb;
            rgbchange = 1;
            if(mode)
                updatemod(&mode->id);
            continue;
        }
        if(command == NONE)
            continue;
        else if(command == DEVICE){
            if(strlen(word) == SERIAL_LEN - 1){
                usbdevice* found = findusb(word);
                if(found){
                    kb = found;
                    set = &kb->setting;
                } else {
                    // If the device isn't plugged in, find (or add) it to storage
                    kb = 0;
                    set = addstore(word);
                }
                profile = (set ? &set->profile : 0);
                mode = (profile ? profile->currentmode : 0);
            }
            continue;
        }
        // Only the DEVICE command is valid without an existing mode
        if(!mode)
            continue;
        if(command == MODE){
            int newmode;
            if(sscanf(word, "%u", &newmode) == 1 && newmode > 0 && newmode < MODE_MAX)
                mode = getusbmode(newmode - 1, profile);
            continue;
        } else if(command == NAME){
            // Name just parses a whole word
            setmodename(mode, word);
            continue;
        } else if(command == PROFILENAME){
            // Same for profile name
            setprofilename(profile, word);
            continue;
        } else if(command == RGB){
            // RGB command has a special response for "on", "off", and a hex constant
            int r, g, b;
            if(!strcmp(word, "on")){
                cmd_ledon(mode);
                continue;
            } else if(!strcmp(word, "off")){
                cmd_ledoff(mode);
                continue;
            } else if(sscanf(word, "%02x%02x%02x", &r, &g, &b) == 3){
                for(int i = 0; i < N_KEYS; i++)
                    cmd_ledrgb(mode, i, word);
                continue;
            }
        } else if(command == MACRO && !strcmp(word, "clear")){
            // Macro has a special clear command
            cmd_macroclear(mode);
            continue;
        }
        // Split the parameter at the colon
        int left = -1;
        sscanf(word, "%*[^:]%n", &left);
        if(left <= 0)
            continue;
        const char* right = word + left;
        if(right[0] == ':')
            right++;
        // Macros have a separate left-side handler
        if(command == MACRO){
            word[left] = 0;
            cmd_macro(mode, word, right);
            continue;
        }
        // Scan the left side for key names and run the request command
        int position = 0, field = 0;
        char keyname[11];
        while(position < left && sscanf(word + position, "%10[^:,]%n", keyname, &field) == 1){
            int keycode;
            if(!strcmp(keyname, "all")){
                // Set all keys
                for(int i = 0; i < N_KEYS; i++)
                    handler(mode, i, right);
            } else if((sscanf(keyname, "#%d", &keycode) && keycode >= 0 && keycode < N_KEYS)
                      || (sscanf(keyname, "#x%x", &keycode) && keycode >= 0 && keycode < N_KEYS)){
                // Set a key numerically
                handler(mode, keycode, right);
            } else {
                // Find this key in the keymap
                for(unsigned i = 0; i < N_KEYS; i++){
                    if(keymap[i].name && !strcmp(keyname, keymap[i].name)){
                        handler(mode, i, right);
                        break;
                    }
                }
            }
            if(word[position += field] == ',')
                position++;
        }
    }
    if(mode && rgbchange)
        updateleds(kb);
}
예제 #23
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Store a word-sized value (return write set entry or NULL).
 */
static inline w_entry_t *stm_write(stm_tx_t *tx, volatile stm_word_t *addr, stm_word_t value, stm_word_t mask)
{
  volatile stm_word_t *lock;
  stm_word_t l, version;
  w_entry_t *w;
  w_entry_t *prev = NULL;

  PRINT_DEBUG2("==> stm_write(t=%p[%lu-%lu],a=%p,d=%p-%lu,m=0x%lx)\n",
               tx, (unsigned long)tx->start, (unsigned long)tx->end, addr, (void *)value, (unsigned long)value, (unsigned long)mask);

  assert(IS_ACTIVE(tx->status));

  if (tx->ro) {
    /* Disable read-only and abort */
    assert(tx->attr != NULL);
    /* Update attributes to inform the caller */
    tx->attr->read_only = 0;
    tx->aborts_ro++;
    stm_rollback(tx, STM_ABORT_RO_WRITE);
    return NULL;
  }

  /* Get reference to lock */
  lock = GET_LOCK(addr);

  /* Try to acquire lock */
 restart:
  l = ATOMIC_LOAD_ACQ(lock);
 restart_no_load:
  if (LOCK_GET_OWNED(l)) {
    /* Locked */
    if (l == LOCK_UNIT) {
      /* Data modified by a unit store: should not last long => retry */
      goto restart;
    }
    /* Do we own the lock? */
    w = (w_entry_t *)LOCK_GET_ADDR(l);
    /* Simply check if address falls inside our write set (avoids non-faulting load) */
    if (tx->w_set.entries <= w && w < tx->w_set.entries + tx->w_set.nb_entries) {
      /* Yes */
      if (mask == 0) {
        /* No need to insert new entry or modify existing one */
        return w;
      }
      prev = w;
      /* Did we previously write the same address? */
      while (1) {
        if (addr == prev->addr) {
          /* No need to add to write set */
          if (mask != ~(stm_word_t)0) {
            if (prev->mask == 0)
              prev->value = ATOMIC_LOAD(addr);
            value = (prev->value & ~mask) | (value & mask);
          }
          prev->value = value;
          prev->mask |= mask;
          return prev;
        }
        if (prev->next == NULL) {
          /* Remember last entry in linked list (for adding new entry) */
          break;
        }
        prev = prev->next;
      }
      /* Get version from previous write set entry (all entries in linked list have same version) */
      version = prev->version;
      /* Must add to write set */
      if (tx->w_set.nb_entries == tx->w_set.size)
        stm_allocate_ws_entries(tx, 1);
      w = &tx->w_set.entries[tx->w_set.nb_entries];
      goto do_write;
    }
    /* Conflict: CM kicks in */
    tx->c_lock = lock;
    /* Abort */
    tx->aborts_locked_write++;
    stm_rollback(tx, STM_ABORT_WW_CONFLICT);
    return NULL;
  }
  /* Not locked */
  /* Handle write after reads (before CAS) */
  version = LOCK_GET_TIMESTAMP(l);
 acquire:
  if (version > tx->end) {
    /* We might have read an older version previously */
    if (!tx->can_extend || stm_has_read(tx, lock) != NULL) {
      /* Read version must be older (otherwise, tx->end >= version) */
      /* Not much we can do: abort */
      tx->aborts_validate_write++;
      stm_rollback(tx, STM_ABORT_VAL_WRITE);
      return NULL;
    }
  }
  /* Acquire lock (ETL) */
  if (tx->w_set.nb_entries == tx->w_set.size)
    stm_allocate_ws_entries(tx, 1);
  w = &tx->w_set.entries[tx->w_set.nb_entries];
  if (ATOMIC_CAS_FULL(lock, l, LOCK_SET_ADDR_WRITE((stm_word_t)w)) == 0)
    goto restart;
  /* We own the lock here (ETL) */
do_write:
  /* Add address to write set */
  w->addr = addr;
  w->mask = mask;
  w->lock = lock;
  if (mask == 0) {
    /* Do not write anything */
#ifndef NDEBUG
    w->value = 0;
#endif /* ! NDEBUG */
  } else
  {
    /* Remember new value */
    if (mask != ~(stm_word_t)0)
      value = (ATOMIC_LOAD(addr) & ~mask) | (value & mask);
    w->value = value;
  }
  w->version = version;
  w->next = NULL;
  if (prev != NULL) {
    /* Link new entry in list */
    prev->next = w;
  }
  tx->w_set.nb_entries++;
  tx->w_set.has_writes++;


  return w;
}
예제 #24
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Called by the CURRENT thread to commit a transaction.
 */
int stm_commit(TXPARAM)
{
  w_entry_t *w;
  stm_word_t t;
  int i;
  TX_GET;

  PRINT_DEBUG("==> stm_commit(%p[%lu-%lu])\n", tx, (unsigned long)tx->start, (unsigned long)tx->end);

  /* Decrement nesting level */
  if (--tx->nesting > 0)
    return 1;

  assert(IS_ACTIVE(tx->status));

  /* A read-only transaction can commit immediately */
  if (tx->w_set.nb_entries == 0)
    goto end;


  /* Update transaction */

  /* Get commit timestamp (may exceed VERSION_MAX by up to MAX_THREADS) */
  t = FETCH_INC_CLOCK + 1;

  /* Try to validate (only if a concurrent transaction has committed since tx->start) */
  if (tx->start != t - 1 && !stm_validate(tx)) {
    /* Cannot commit */
    tx->aborts_validate_commit++;
    stm_rollback(tx, STM_ABORT_VALIDATE);
    return 0;
  }

  /* Install new versions, drop locks and set new timestamp */
  w = tx->w_set.entries;
  for (i = tx->w_set.nb_entries; i > 0; i--, w++) {
    if (w->mask != 0)
      ATOMIC_STORE(w->addr, w->value);
    /* Only drop lock for last covered address in write set */
    if (w->next == NULL)
      ATOMIC_STORE_REL(w->lock, LOCK_SET_TIMESTAMP(t));
  }

 end:
  tx->retries = 0;



  /* Callbacks */
  if (nb_commit_cb != 0) {
    int cb;
    for (cb = 0; cb < nb_commit_cb; cb++)
      commit_cb[cb].f(TXARGS commit_cb[cb].arg);
  }


  /* Set status to COMMITTED */
  SET_STATUS(tx->status, TX_COMMITTED);

  return 1;
}
예제 #25
0
static void
ok_button_clicked (GtkWidget  *button,
		   DialogData *data)
{
	GthChangeFields  change_fields;
	GthChangeType    change_type;
	GthDateTime     *date_time;
	int              time_adjustment;
	GthTask         *task;

	date_time = NULL;

	change_fields = 0;
	if (IS_ACTIVE (GET_WIDGET ("change_last_modified_checkbutton")))
		change_fields |= GTH_CHANGE_LAST_MODIFIED_DATE;
	if (IS_ACTIVE (GET_WIDGET ("change_comment_checkbutton")))
		change_fields |= GTH_CHANGE_COMMENT_DATE;

	change_type = 0;
	time_adjustment = 0;
	if (IS_ACTIVE (GET_WIDGET ("to_following_date_radiobutton"))) {
		change_type = GTH_CHANGE_TO_FOLLOWING_DATE;
		date_time = gth_datetime_new ();
		gth_time_selector_get_value (GTH_TIME_SELECTOR (data->date_selector), date_time);
	}
	else if (IS_ACTIVE (GET_WIDGET ("to_last_modified_date_radiobutton")))
		change_type = GTH_CHANGE_TO_FILE_MODIFIED_DATE;
	else if (IS_ACTIVE (GET_WIDGET ("to_creation_date_radiobutton")))
		change_type = GTH_CHANGE_TO_FILE_CREATION_DATE;
	else if (IS_ACTIVE (GET_WIDGET ("to_photo_original_date_radiobutton")))
		change_type = GTH_CHANGE_TO_PHOTO_ORIGINAL_DATE;
	else if (IS_ACTIVE (GET_WIDGET ("adjust_time_radiobutton"))) {
		change_type = GTH_CHANGE_ADJUST_TIME;
		time_adjustment = (HOURS_TO_SECONDS (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_h_spinbutton"))))
				   + MINS_TO_SECONDS (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_m_spinbutton"))))
				   + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("adjust_time_s_spinbutton"))));
		if (gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("adjust_sign_combobox"))) == 1)
			time_adjustment = -time_adjustment;
	}

	/* save the preferences */

	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_SET_LAST_MODIFIED_DATE, (change_fields & GTH_CHANGE_LAST_MODIFIED_DATE) == GTH_CHANGE_LAST_MODIFIED_DATE);
	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_SET_COMMENT_DATE, (change_fields & GTH_CHANGE_COMMENT_DATE) == GTH_CHANGE_COMMENT_DATE);

	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FOLLOWING_DATE, change_type == GTH_CHANGE_TO_FOLLOWING_DATE);
	if (change_type == GTH_CHANGE_TO_FOLLOWING_DATE) {
		char *s;
		s = gth_datetime_to_exif_date (date_time);
		g_settings_set_string (data->settings, PREF_CHANGE_DATE_DATE, s);
		g_free (s);
	}
	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_MODIFIED_DATE, change_type == GTH_CHANGE_TO_FILE_MODIFIED_DATE);
	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_FILE_CREATION_DATE, change_type == GTH_CHANGE_TO_FILE_CREATION_DATE);
	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_TO_PHOTO_ORIGINAL_DATE, change_type == GTH_CHANGE_TO_PHOTO_ORIGINAL_DATE);
	g_settings_set_boolean (data->settings, PREF_CHANGE_DATE_ADJUST_TIME, change_type == GTH_CHANGE_ADJUST_TIME);
	if (change_type == GTH_CHANGE_ADJUST_TIME)
		g_settings_set_int (data->settings, PREF_CHANGE_DATE_TIME_ADJUSTMENT, time_adjustment);

	/* exec the task */

	task = gth_change_date_task_new (gth_browser_get_location (data->browser),
					 data->file_list,
					 change_fields,
					 change_type,
					 date_time,
					 time_adjustment);
	gth_browser_exec_task (data->browser, task, FALSE);
	gtk_widget_destroy (data->dialog);

	g_object_unref (task);
	gth_datetime_free (date_time);
}
예제 #26
0
int openusb(struct udev_device* dev, int model){
    // Make sure it's not connected yet
    const char* path = udev_device_get_devnode(dev);
    for(int i = 1; i < DEV_MAX; i++){
        if(keyboard[i].udev && !strcmp(path, udev_device_get_devnode(keyboard[i].udev)))
            return 0;
    }
    // Find a free USB slot
    for(int index = 1; index < DEV_MAX; index++){
        usbdevice* kb = keyboard + index;
        if(!IS_ACTIVE(kb)){
            // Open the sysfs device
            kb->udev = dev;
            kb->handle = open(path, O_RDWR);
            kb->model = model;
            if(kb->handle <= 0){
                printf("Error: Failed to open USB device: %s\n", strerror(errno));
                closehandle(kb);
                connectstatus |= 2;
                return -1;
            }

            // Copy device description and serial
            strncpy(kb->name, udev_device_get_sysattr_value(dev, "product"), NAME_LEN);
            strncpy(kb->setting.serial, udev_device_get_sysattr_value(dev, "serial"), SERIAL_LEN);
            printf("Connecting %s (S/N: %s)\n", kb->name, kb->setting.serial);

            // A USB reset is almost always required in order for it to work correctly
            printf("Resetting device\n");
            if(ioctl(kb->handle, USBDEVFS_RESET, 0)){
                printf("Reset failed (%s). Disconnecting.\n", strerror(errno));
                closehandle(kb);
                connectstatus |= 2;
                return -1;
            }

            // Claim the USB interfaces
            if(usbclaim(kb)){
                printf("Error: Failed to claim interface: %s\n", strerror(errno));
                closehandle(kb);
                connectstatus |= 2;
                return -1;
            }

            // Put the M-keys (K95) as well as the Brightness/Lock keys into software-controlled mode. This packet disables their
            // hardware-based functions.
            unsigned char datapkt[MSG_SIZE] = { 0x07, 0x04, 0x02 };
            struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0300, 0x03, MSG_SIZE, 500, datapkt };
            // This packet doesn't always succeed, so reset the device if that happens
            if(ioctl(kb->handle, USBDEVFS_CONTROL, &transfer) != MSG_SIZE){
                printf("Couldn't talk to device (%s), trying to reset again...\n", strerror(errno));
                if(resetusb(kb) || ioctl(kb->handle, USBDEVFS_CONTROL, &transfer) != MSG_SIZE){
                    printf("Reset failed (%s). Disconnecting.\n", strerror(errno));
                    closehandle(kb);
                    connectstatus |= 2;
                    return -1;
                }
            }

            // Set up the device
            if(setupusb(index)){
                closehandle(kb);
                connectstatus |= 2;
                return -1;
            }

            // Set up the interrupt transfers.
            kb->INPUT_TEST = 0;
            setint(kb);

            // We should receive an interrupt transfer shortly after setting them up. If it doesn't happen, the device
            // isn't working correctly and needs to be reset
            int received = 0;
            for(int wait = 0; wait < 10; wait++){
                usleep(50000);
                if(kb->INPUT_TEST){
                    received = 1;
                    break;
                }
            }
            if(!received){
                printf("Didn't get input, trying to reset again...\n");
                if(resetusb(kb)){
                    printf("Reset failed (%s). Disconnecting.\n", strerror(errno));
                    closehandle(kb);
                    connectstatus |= 2;
                    return -1;
                }
            }

            updateconnected();
            printf("Device ready at %s%d\n", devpath, index);
            connectstatus |= 1;
            return 0;
        }
    }
    printf("Error: No free devices\n");
    return -1;
}
예제 #27
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Called by the CURRENT thread to inquire about the status of a transaction.
 */
int stm_active(TXPARAM)
{
  TX_GET;

  return IS_ACTIVE(tx->status);
}
예제 #28
0
/*
 * Set the CURRENT transaction as irrevocable.
 */
static INLINE int
int_stm_set_irrevocable(stm_tx_t *tx, int serial)
{
#ifdef IRREVOCABLE_ENABLED
# if CM == CM_MODULAR
    stm_word_t t;
# endif /* CM == CM_MODULAR */

    if (!IS_ACTIVE(tx->status) && serial != -1) {
        /* Request irrevocability outside of a transaction or in abort handler (for next execution) */
        tx->irrevocable = 1 + (serial ? 0x08 : 0);
        return 0;
    }

    /* Are we already in irrevocable mode? */
    if ((tx->irrevocable & 0x07) == 3) {
        return 1;
    }

    if (tx->irrevocable == 0) {
        /* Acquire irrevocability for the first time */
        tx->irrevocable = 1 + (serial ? 0x08 : 0);
#ifdef HYBRID_ASF
        /* TODO: we shouldn't use pthread_mutex/cond since it could use syscall. */
        if (tx->software == 0) {
            asf_abort(ASF_RETRY_IRREVOCABLE);
            return 0;
        }
#endif /* HYBRID_ASF */
        /* Try acquiring global lock */
        if (_tinystm.irrevocable == 1 || ATOMIC_CAS_FULL(&_tinystm.irrevocable, 0, 1) == 0) {
            /* Transaction will acquire irrevocability after rollback */
            stm_rollback(tx, STM_ABORT_IRREVOCABLE);
            return 0;
        }
        /* Success: remember we have the lock */
        tx->irrevocable++;
        /* Try validating transaction */
#if DESIGN == WRITE_BACK_ETL
        if (!stm_wbetl_validate(tx)) {
            stm_rollback(tx, STM_ABORT_VALIDATE);
            return 0;
        }
#elif DESIGN == WRITE_BACK_CTL
        if (!stm_wbctl_validate(tx)) {
            stm_rollback(tx, STM_ABORT_VALIDATE);
            return 0;
        }
#elif DESIGN == WRITE_THROUGH
        if (!stm_wt_validate(tx)) {
            stm_rollback(tx, STM_ABORT_VALIDATE);
            return 0;
        }
#elif DESIGN == MODULAR
        if ((tx->attr.id == WRITE_BACK_CTL && stm_wbctl_validate(tx))
                || (tx->attr.id == WRITE_THROUGH && stm_wt_validate(tx))
                || (tx->attr.id != WRITE_BACK_CTL && tx->attr.id != WRITE_THROUGH && stm_wbetl_validate(tx))) {
            stm_rollback(tx, STM_ABORT_VALIDATE);
            return 0;
        }
#endif /* DESIGN == MODULAR */

# if CM == CM_MODULAR
        /* We might still abort if we cannot set status (e.g., we are being killed) */
        t = tx->status;
        if (GET_STATUS(t) != TX_ACTIVE || ATOMIC_CAS_FULL(&tx->status, t, t + (TX_IRREVOCABLE - TX_ACTIVE)) == 0) {
            stm_rollback(tx, STM_ABORT_KILLED);
            return 0;
        }
# endif /* CM == CM_MODULAR */
        if (serial && tx->w_set.nb_entries != 0) {
            /* TODO: or commit the transaction when we have the irrevocability. */
            /* Don't mix transactional and direct accesses => restart with direct accesses */
            stm_rollback(tx, STM_ABORT_IRREVOCABLE);
            return 0;
        }
    } else if ((tx->irrevocable & 0x07) == 1) {
        /* Acquire irrevocability after restart (no need to validate) */
        while (_tinystm.irrevocable == 1 || ATOMIC_CAS_FULL(&_tinystm.irrevocable, 0, 1) == 0)
            ;
        /* Success: remember we have the lock */
        tx->irrevocable++;
    }
    assert((tx->irrevocable & 0x07) == 2);

    /* Are we in serial irrevocable mode? */
    if ((tx->irrevocable & 0x08) != 0) {
        /* Stop all other threads */
        if (stm_quiesce(tx, 1) != 0) {
            /* Another thread is quiescing and we are active (trying to acquire irrevocability) */
            assert(serial != -1);
            stm_rollback(tx, STM_ABORT_IRREVOCABLE);
            return 0;
        }
    }

    /* We are in irrevocable mode */
    tx->irrevocable++;

#else /* ! IRREVOCABLE_ENABLED */
    fprintf(stderr, "Irrevocability is not supported in this configuration\n");
    exit(-1);
#endif /* ! IRREVOCABLE_ENABLED */
    return 1;
}
예제 #29
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Rollback transaction.
 */
static inline void stm_rollback(stm_tx_t *tx, int reason)
{
  w_entry_t *w;
  int i;

  PRINT_DEBUG("==> stm_rollback(%p[%lu-%lu])\n", tx, (unsigned long)tx->start, (unsigned long)tx->end);

  assert(IS_ACTIVE(tx->status));

  /* Drop locks */
  i = tx->w_set.nb_entries;
  if (i > 0) {
    w = tx->w_set.entries;
    for (; i > 0; i--, w++) {
      if (w->next == NULL) {
        /* Only drop lock for last covered address in write set */
        ATOMIC_STORE(w->lock, LOCK_SET_TIMESTAMP(w->version));
      }
    }
    /* Make sure that all lock releases become visible */
    ATOMIC_MB_WRITE;
  }


  tx->retries++;
  tx->aborts++;
  if (tx->retries == 1)
    tx->aborts_1++;
  else if (tx->retries == 2)
    tx->aborts_2++;
  if (tx->max_retries < tx->retries)
    tx->max_retries = tx->retries;

  /* Callbacks */
  if (nb_abort_cb != 0) {
    int cb;
    for (cb = 0; cb < nb_abort_cb; cb++)
      abort_cb[cb].f(TXARGS abort_cb[cb].arg);
  }

  /* Set status to ABORTED */
  SET_STATUS(tx->status, TX_ABORTED);

  /* Reset nesting level */
  tx->nesting = 1;


  /* Wait until contented lock is free */
  if (tx->c_lock != NULL) {
    /* Busy waiting (yielding is expensive) */
    while (LOCK_GET_OWNED(ATOMIC_LOAD(tx->c_lock))) {
      sched_yield();
    }
    tx->c_lock = NULL;
  }

  /* Reset field to restart transaction */
  stm_prepare(tx);

  /* Jump back to transaction start */
  if (tx->attr == NULL || !tx->attr->no_retry)
    siglongjmp(tx->env, reason);
}
예제 #30
0
파일: stm.o.c 프로젝트: nmldiegues/jvm-stm
/*
 * Load a word-sized value (invisible read).
 */
static inline stm_word_t stm_read_invisible(stm_tx_t *tx, volatile stm_word_t *addr)
{
  volatile stm_word_t *lock;
  stm_word_t l, l2, value, version;
  r_entry_t *r;
  w_entry_t *w;

  PRINT_DEBUG2("==> stm_read_invisible(t=%p[%lu-%lu],a=%p)\n", tx, (unsigned long)tx->start, (unsigned long)tx->end, addr);

  assert(IS_ACTIVE(tx->status));


  /* Get reference to lock */
  lock = GET_LOCK(addr);

  /* Note: we could check for duplicate reads and get value from read set */

  /* Read lock, value, lock */
 restart:
  l = ATOMIC_LOAD_ACQ(lock);
 restart_no_load:
  if (LOCK_GET_WRITE(l)) {
    /* Locked */
    if (l == LOCK_UNIT) {
      /* Data modified by a unit store: should not last long => retry */
      goto restart;
    }
    /* Do we own the lock? */
    w = (w_entry_t *)LOCK_GET_ADDR(l);
    /* Simply check if address falls inside our write set (avoids non-faulting load) */
    if (tx->w_set.entries <= w && w < tx->w_set.entries + tx->w_set.nb_entries) {
      /* Yes: did we previously write the same address? */
      while (1) {
        if (addr == w->addr) {
          /* Yes: get value from write set (or from memory if mask was empty) */
          value = (w->mask == 0 ? ATOMIC_LOAD(addr) : w->value);
          break;
        }
        if (w->next == NULL) {
          /* No: get value from memory */
          value = ATOMIC_LOAD(addr);
          break;
        }
        w = w->next;
      }
      /* No need to add to read set (will remain valid) */
      return value;
    }
    /* Conflict: CM kicks in (we could also check for duplicate reads and get value from read set) */
    tx->c_lock = lock;
    /* Abort */
    tx->aborts_locked_read++;
    stm_rollback(tx, STM_ABORT_RW_CONFLICT);
    return 0;
  } else {
    /* Not locked */
    value = ATOMIC_LOAD_ACQ(addr);
    l2 = ATOMIC_LOAD_ACQ(lock);
    if (l != l2) {
      l = l2;
      goto restart_no_load;
    }
    /* Check timestamp */
    version = LOCK_GET_TIMESTAMP(l);
    /* Valid version? */
    if (version > tx->end) {
      /* No: try to extend first (except for read-only transactions: no read set) */
      if (tx->ro || !tx->can_extend || !stm_extend(tx)) {
        /* Not much we can do: abort */
        tx->aborts_validate_read++;
        stm_rollback(tx, STM_ABORT_VAL_READ);
        return 0;
      }
      /* Verify that version has not been overwritten (read value has not
       * yet been added to read set and may have not been checked during
       * extend) */
      l = ATOMIC_LOAD_ACQ(lock);
      if (l != l2) {
        l = l2;
        goto restart_no_load;
      }
      /* Worked: we now have a good version (version <= tx->end) */
    }
  }
  /* We have a good version: add to read set (update transactions) and return value */

  if (!tx->ro) {
    /* Add address and version to read set */
    if (tx->r_set.nb_entries == tx->r_set.size)
      stm_allocate_rs_entries(tx, 1);
    r = &tx->r_set.entries[tx->r_set.nb_entries++];
    r->version = version;
    r->lock = lock;
  }
  return value;
}