static inline void
rwlock_rlock(struct rwlock *lock) {
	for (;;) {
		while(lock->write) {
			atom_sync();
		}
		atom_inc(&lock->read);
		if (lock->write) {
			atom_dec(&lock->read);
		} else {
			break;
		}
	}
}
Ejemplo n.º 2
0
void *
index_grab(struct index *idx, id_t id) {
  struct slot *slot;
  void *ud;
  if (id == 0) return 0;
  rwlock_rlock(&idx->lock);
  slot = &idx->slot[HASH(id)];
  if (slot->id != id) {
    rwlock_runlock(&idx->lock);
    return 0;
  }
  atom_inc(&slot->ref);
  ud = slot->ud;
  rwlock_runlock(&idx->lock);
  return ud;
}
Ejemplo n.º 3
0
void *
handlemap_grab(struct handlemap *m, handleid id) {
	struct handleslot * slot;
	void * ud;
	if (id == 0)
		return NULL;
	rwlock_rlock(&m->lock);
	slot = &m->slot[id & (m->cap - 1)];
	if (slot->id != id) {
		rwlock_runlock(&m->lock);
		return NULL;
	}
	atom_inc(&slot->ref);
	ud = slot->ud;
	rwlock_runlock(&m->lock);
	return ud;
}
Ejemplo n.º 4
0
static int socket_next_id(void) {
	int i;
	for (i = 0; i < MAX_SOCKET; i++) {
		struct socket *sock;
		int id = atom_inc(&(S.next_id));
		if (id < 0) {
			id = atom_and(&(S.next_id), 0x7fffffff);
		}
		sock = &S.slot[HASH_ID(id)];
		if (sock->type == SOCKET_TYPE_INVALID) {
			if (atom_cas(&(sock->type), SOCKET_TYPE_INVALID, SOCKET_TYPE_RESERVE)) {
				sock->id = id;
				sock->fd = -1;
				return id;
			}
			--i;
		}
	}
	return -1;
}
Ejemplo n.º 5
0
struct skynet_service *
skynet_service_grab(address_t id) {
	if (id == 0)
		return NULL;
	struct service_node *sn = &G->s[id % MAX_SERVICE];
	if (sn->exit || sn->id != id)
		return NULL;
	atom_inc(&sn->ref);
	if (sn->exit) {
		// double check, service may exit after inc ref
		// .ref never inc after .exit set
		atom_dec(&sn->ref);
		return NULL;
	}
	// the ref is great than 1, so .svc is safe now
	if (skynet_service_id(sn->svc) != id) {
		atom_dec(&sn->ref);
		return NULL;
	}
	return sn->svc;
}
Ejemplo n.º 6
0
int32_t _bus_terminal_init_attach(bus_terminal_t* bt, int16_t key)
{
    int32_t buskey = (key << 16);
    int32_t i;
    struct shm_t* shm;
    int32_t registered = -1;

    // attach exsit shm
    shm = shm_create(buskey, sizeof(bus_t), 1);
    if (!shm) {
        return -1;
    }
    bt->bus = (bus_t*)shm_mem(shm);

    // invalid shm data
    if (bt->bus->key != buskey || bt->bus->size != sizeof(bus_t)) {
        return -1;
    }

    // register terminal info
    for (i = 0; i < bt->bus->terminal_count; ++ i) {
        if (bt->bus->terminals[i] == bt->self) {
            registered = 0;
            break;
        }
    }
    if (registered != 0) {
        if (bt->bus->terminal_count >= BUS_MAX_TERMINAL_COUNT) {
            return -1;
        } else {
            bt->bus->terminals[bt->bus->terminal_count ++] = bt->self;
            atom_inc(&bt->bus->terminal_version);
        }
    }
    return 0;
}
Ejemplo n.º 7
0
int32_t _bus_terminal_register_channel(bus_terminal_t* bt, bus_addr_t to, size_t sz)
{
    int i, found, ret;
    struct bus_channel_t* bc;
    struct bus_terminal_channel_t* btc;
    if (!bt) return bus_err_fail;

    // make sure same version
    bus_terminal_tick(bt);

    // add lock
    process_lock_lock(bt->lock);
    if (bt->local_channel_version != bt->bus->channel_version) {
        process_lock_unlock(bt->lock);
        return bus_err_fail;
    }

    // no left free channel
    if (bt->bus->channel_count >= BUS_MAX_CHANNLE_COUNT) {
        process_lock_unlock(bt->lock);
        return bus_err_channel_full;
    }

    // check terminals
    found = -1;
    for (i = 0; i < bt->bus->terminal_count; ++ i) {
        if (bt->bus->terminals[i] == to) {
            found = 0;
            break;
        }
    }
    if (found) {
        process_lock_unlock(bt->lock);
        return bus_err_peek_fail;
    }

    // check not self (no loop bus)
    if (to == bt->self) {
        process_lock_unlock(bt->lock);
        return bus_err_peek_fail;
    }

    // create channel
    bc = &bt->bus->channels[bt->bus->channel_count];
    bc->from = bt->self;
    bc->to = to;
    bc->shmkey = bt->bus->key + (++ bt->bus->channel_key);
    bc->channel_size = sz;
    btc = bus_terminal_channel_init(bc->shmkey, bc->from, bc->to, bc->channel_size, 0);
    if (!btc) {
        process_lock_unlock(bt->lock);
        return bus_err_channel_fail;
    }

    // add terminal-channel to idtable
    ret = idtable_add(bt->send_channels, bc->to, btc);
    assert(0 == ret);

    // add channel version
    ++ bt->bus->channel_count;
    atom_inc(&bt->bus->channel_version);
    process_lock_unlock(bt->lock);
    bt->local_channel_version = bt->bus->channel_version;
    return bus_ok;
}
Ejemplo n.º 8
0
void
skynet_message_grab(struct skynet_message *msg) {
	assert(msg->ref > 0);
	atom_inc(&msg->ref);
}
Ejemplo n.º 9
0
			void retain() { atom_inc(&ref_); }
Ejemplo n.º 10
0
static inline void service_total_inc(void) {
	atom_inc(&g.total);
}
Ejemplo n.º 11
0
void monitor_trigger(struct monitor *monitor, uint32_t source, uint32_t handle) {
	monitor->source = source;
	monitor->handle = handle;
	atom_inc(&monitor->version);
}