void leave_bar() { semaphore_up(bouncer); left_counter++; if(entered_counter >= S && left_counter == entered_counter){ printf(1, "\n@@@@\n"); binary_semaphore_up(lk); semaphore_up(exit_lk); } }
/* * Remove msg from sent queue. * Return 0 if message should be deleted from store and 1 if not (e.g. tmp nack) */ static void boxc_sent_pop(Boxc *conn, Msg *m, Msg **orig) { Octstr *os; char id[UUID_STR_LEN + 1]; Msg *msg; if (conn->is_wap || !conn->sent || !m || (msg_type(m) != ack && msg_type(m) != sms)) return; if (orig != NULL) *orig = NULL; uuid_unparse((msg_type(m) == sms ? m->sms.id : m->ack.id), id); os = octstr_create(id); msg = dict_remove(conn->sent, os); octstr_destroy(os); if (!msg) { error(0, "BOXC: Got ack for nonexistend message!"); msg_dump(m, 0); return; } semaphore_up(conn->pending); if (orig == NULL) msg_destroy(msg); else *orig = msg; }
void object_wait_signal(void *sync) { struct object_wait_sync *s; s = (struct object_wait_sync *)sync; s->signalled = TRUE; semaphore_up(s->sem, 1); }
static int thread_func(void *data) { sem_id *psid = (sem_id*)data; /* signal semaphore */ semaphore_up(*psid, 1); return 0; }
void return_cup(struct Cup* c) { BB_put(dbb, c); dc_count++; if(get_dc_percent()>60){ printf(1, "wakeup cupboy!\n"); semaphore_up(cupboy_lk); } }
static void producer(void *arg) { thread_detach(THREAD); waitq_sleep(&can_start); semaphore_down(&sem); atomic_inc(&items_produced); thread_usleep(250); semaphore_up(&sem); }
static void consumer(void *arg) { thread_detach(THREAD); waitq_sleep(&can_start); semaphore_down(&sem); atomic_inc(&items_consumed); thread_usleep(500); semaphore_up(&sem); }
/** * Up (increase the count of) a semaphore. * * Increases the count of a semaphore by the specified number. This can cause * waiting threads to be woken. * * @param handle Handle to semaphore to up. * @param count Value to up the semaphore by. * * @return Status code describing result of the operation. */ status_t kern_semaphore_up(handle_t handle, size_t count) { object_handle_t *khandle; user_semaphore_t *sem; status_t ret; ret = object_handle_lookup(handle, OBJECT_TYPE_SEMAPHORE, SEMAPHORE_RIGHT_USAGE, &khandle); if(ret != STATUS_SUCCESS) return ret; sem = (user_semaphore_t *)khandle->object; semaphore_up(&sem->sem, count); object_handle_release(khandle); return STATUS_SUCCESS; }
/* Enqueues a message onto * a message box. If the * message box is full, the * process will block until * it can add the item. * You may assume that the * message box ID has been * properly opened before this * call. * The message is 'nbytes' bytes * starting at 'msg' */ void do_mbox_send(mbox_t mbox, void *msg, int nbytes) { (void)mbox; (void)msg; (void)nbytes; // fill this in MessageBox mb = MessageBoxen[mbox]; semaphore_down(&mb.empty_count); //lock_acquire(&mb.lock); bcopy(msg, mb.messages[mb.end].msg, nbytes); mb.end = (mb.end + 1) % BUFFER_LENGTH; //lock_release(&mb.lock); semaphore_up(&mb.full_count); }
void evdev_post_event(dev_t device, struct input_event event) { evdev_event_t *ev; evdev_device_t *dev = evdev_get(device); assert(dev != NULL); ev = heapmm_alloc(sizeof(evdev_event_t)); ev->event = event; ev->event.time.tv_sec = (time_t) system_time; ev->event.time.tv_usec = (time_t) system_time_micros; llist_add_end(&(dev->queue), (llist_t *) ev); dev->queue_count++; if (dev->queue_count == CONFIG_EVDEV_QUEUE_SIZE) { ev = (evdev_event_t *)llist_remove_first(&(dev->queue)); heapmm_free(ev, sizeof(evdev_event_t)); dev->queue_count--; } semaphore_up(&(dev->event_wait)); }
/** * Add an event to an input device's buffer. * * Adds an event to an input device's event buffer. This function is safe to * use from interrupt context. * * @param _device Device to add to. * @param type Type of event. * @param value Value of event. */ void input_device_event(device_t *_device, uint8_t type, int32_t value) { input_device_t *device = _device->data; size_t i; spinlock_lock(&device->lock); /* Drop the input if full or device is not open. */ if(!atomic_get(&device->open) || device->size == INPUT_BUFFER_SIZE) { spinlock_unlock(&device->lock); return; } i = (device->start + device->size++) % INPUT_BUFFER_SIZE; device->buffer[i].time = system_time(); device->buffer[i].type = type; device->buffer[i].value = value; semaphore_up(&device->sem, 1); notifier_run_unlocked(&device->data_notifier, NULL, false); spinlock_unlock(&device->lock); }
/* Receives a message from the * specified message box. If * empty, the process will block * until it can remove an item. * You may assume that the * message box has been properly * opened before this call. * The message is copied into * 'msg'. No more than * 'nbytes' bytes will be copied * into this buffer; longer * messages will be truncated. */ void do_mbox_recv(mbox_t mbox, void *msg, int nbytes) { //asm("xchg %bx,%bx"); (void)mbox; (void)msg; (void)nbytes; // fill this in MessageBox mb = MessageBoxen[mbox]; //asm("xchg %bx, %bx"); printf(10, 0, "%d", mb.full_count.value); printf(11, 0, "%d", mb.empty_count.value); asm("xchg %bx, %bx"); semaphore_down(&mb.full_count); //lock_acquire(&mb.lock); bcopy(mb.messages[mb.start].msg, msg, nbytes); mb.start = (mb.start + 1) % BUFFER_LENGTH; //lock_release(&mb.lock); semaphore_up(&mb.empty_count); printf(10, 0, "%d", mb.full_count.value); printf(11, 0, "%d", mb.empty_count.value); asm("xchg %bx, %bx"); }
/* * Thread to handle finished sendings */ static void httpsmsc_send_cb(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; Msg *msg; int status; List *headers; Octstr *final_url, *body; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) { msg = http_receive_result(conndata->http_ref, &status, &final_url, &headers, &body); if (msg == NULL) break; /* they told us to die, by unlocking */ counter_decrease(conndata->open_sends); if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); /* Handle various states here. */ /* request failed and we are not in shutdown mode */ if (status == -1 && conndata->shutdown == 0) { error(0, "HTTP[%s]: Couldn't connect to SMS center." "(retrying in %ld seconds) %ld.", octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends)); mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_RECONNECTING; mutex_unlock(conn->flow_mutex); /* XXX how should we know whether it's temp. error ?? */ bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); /* * Just sleep reconnect delay and set conn to ACTIVE again; * otherwise if no pending request are here, we leave conn in * RECONNECTING state for ever and no routing (trials) take place. */ if (counter_value(conndata->open_sends) == 0) { gwthread_sleep(conn->reconnect_delay); /* and now enable routing again */ mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } continue; } /* request failed and we *are* in shutdown mode, drop the message */ else if (status == -1 && conndata->shutdown == 1) { bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); } /* request succeeded */ else { /* we received a response, so this link is considered online again */ if (conn->status != SMSCCONN_ACTIVE) { mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_ACTIVE; time(&conn->connect_time); mutex_unlock(conn->flow_mutex); /* tell bearerbox core that we are connected again */ bb_smscconn_connected(conn); } conndata->callbacks->parse_reply(conn, msg, status, headers, body); } http_destroy_headers(headers); octstr_destroy(final_url); octstr_destroy(body); } debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying", octstr_get_cstr(conn->id)); conndata->shutdown = 1; if (counter_value(conndata->open_sends)) { warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.", octstr_get_cstr(conn->id), counter_value(conndata->open_sends)); } }
/* * Thread to send queued messages */ static void httpsmsc_sender(void *arg) { SMSCConn *conn = arg; ConnData *conndata = conn->data; Msg *msg; double delay = 0; /* Make sure we log into our own log-file if defined */ log_thread_to(conn->log_idx); if (conn->throughput) { delay = 1.0 / conn->throughput; } while (conndata->shutdown == 0) { /* check if we can send ; otherwise block on semaphore */ if (conndata->max_pending_sends) semaphore_down(conndata->max_pending_sends); if (conndata->shutdown) { if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); break; } msg = gwlist_consume(conndata->msg_to_send); if (msg == NULL) break; /* obey throughput speed limit, if any */ if (conn->throughput > 0) { gwthread_sleep(delay); } counter_increase(conndata->open_sends); if (conndata->callbacks->send_sms(conn, msg) == -1) { counter_decrease(conndata->open_sends); if (conndata->max_pending_sends) semaphore_up(conndata->max_pending_sends); } } /* put outstanding sends back into global queue */ while((msg = gwlist_extract_first(conndata->msg_to_send))) bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL); /* if there no receiver shutdown */ if (conndata->port <= 0) { /* unblock http_receive_result() if there are no open sends */ if (counter_value(conndata->open_sends) == 0) http_caller_signal_shutdown(conndata->http_ref); if (conndata->send_cb_thread != -1) { gwthread_wakeup(conndata->send_cb_thread); gwthread_join(conndata->send_cb_thread); } mutex_lock(conn->flow_mutex); conn->status = SMSCCONN_DEAD; mutex_unlock(conn->flow_mutex); if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL) conndata->callbacks->destroy(conn); conn->data = NULL; conndata_destroy(conndata); bb_smscconn_killed(); } }
static void run_smsbox(void *arg) { Boxc *newconn; long sender; Msg *msg; List *keys; Octstr *key; gwlist_add_producer(flow_threads); newconn = arg; newconn->incoming = gwlist_create(); gwlist_add_producer(newconn->incoming); newconn->retry = incoming_sms; newconn->outgoing = outgoing_sms; newconn->sent = dict_create(smsbox_max_pending, NULL); newconn->pending = semaphore_create(smsbox_max_pending); sender = gwthread_create(boxc_sender, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); goto cleanup; } /* * We register newconn in the smsbox_list here but mark newconn as routable * after identification or first message received from smsbox. So we can avoid * a race condition for routable smsboxes (otherwise between startup and * registration we will forward some messages to smsbox). */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_append(smsbox_list, newconn); gw_rwlock_unlock(smsbox_list_rwlock); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); gwlist_remove_producer(newconn->outgoing); /* remove us from smsbox routing list */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_delete_equal(smsbox_list, newconn); if (newconn->boxc_id) { dict_remove(smsbox_by_id, newconn->boxc_id); } gw_rwlock_unlock(smsbox_list_rwlock); /* * check if we in the shutdown phase and sms dequeueing thread * has removed the producer already */ if (gwlist_producer_count(newconn->incoming) > 0) gwlist_remove_producer(newconn->incoming); /* check if we are still waiting for ack's and semaphore locked */ if (dict_key_count(newconn->sent) >= smsbox_max_pending) semaphore_up(newconn->pending); /* allow sender to go down */ gwthread_join(sender); /* put not acked msgs into incoming queue */ keys = dict_keys(newconn->sent); while((key = gwlist_extract_first(keys)) != NULL) { msg = dict_remove(newconn->sent, key); gwlist_produce(incoming_sms, msg); octstr_destroy(key); } gw_assert(gwlist_len(keys) == 0); gwlist_destroy(keys, octstr_destroy_item); /* clear our send queue */ while((msg = gwlist_extract_first(newconn->incoming)) != NULL) { gwlist_produce(incoming_sms, msg); } cleanup: gw_assert(gwlist_len(newconn->incoming) == 0); gwlist_destroy(newconn->incoming, NULL); gw_assert(dict_key_count(newconn->sent) == 0); dict_destroy(newconn->sent); semaphore_destroy(newconn->pending); boxc_destroy(newconn); /* wakeup the dequeueing thread */ gwthread_wakeup(sms_dequeue_thread); gwlist_remove_producer(flow_threads); }
int _sys_msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) { size_t sendsz = sizeof(long int) + msgsz; msg_info_t *info; sysv_msg_t *msg; const long int *mtype = (const long int *) msgp; assert(msgp != NULL); info = msg_get_by_id(msqid); if (!info) { syscall_errno = EINVAL; return -1; } if (!ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_WRITE)) { syscall_errno = EACCES; return -1; } if ((*mtype) < 1) { syscall_errno = EINVAL; return -1; } if (info->del) { syscall_errno = EIDRM; return -1; } if (info->used_bytes >= info->info.msg_qbytes) { if (msgflg & IPC_NOWAIT) { syscall_errno = EAGAIN; return -1; } info->refs++; while (info->used_bytes >= info->info.msg_qbytes) { if (semaphore_idown(info->swaitsem)) { info->refs--; if (info->del && !info->refs) msg_do_delete(info); syscall_errno = EINTR; return -1; } if (info->del) { info->refs--; if (!info->refs) msg_do_delete(info); syscall_errno = EIDRM; return -1; } } info->refs--; } msg = heapmm_alloc(sizeof(sysv_msg_t)); if (!msg) { syscall_errno = ENOMEM; return -1; } msg->msize = sendsz; msg->mtype = *mtype; msg->mtext = heapmm_alloc(msg->msize); if (!msg->mtext) { heapmm_free(msg, sizeof(sysv_msg_t)); syscall_errno = ENOMEM; return -1; } memcpy(msg->mtext, msgp, sendsz); info->info.msg_qnum++; info->used_bytes += sendsz; info->info.msg_lspid = scheduler_current_task->pid; info->info.msg_stime = (time_t) system_time; llist_add_end(&(info->msgs), (llist_t *) msg); semaphore_up(info->rwaitsem); return 0; }
void lock_release(Lock *lock) { assert(semaphore_value(&lock->sema) == 0); semaphore_up(&lock->sema, 1); }
ssize_t _sys_msgrcv(int msqid, void *msgp, size_t msgsz, long int msgtyp, int msgflg) { size_t readsz; msg_info_t *info; sysv_msg_t *msg; assert(msgp != NULL); msgsz += sizeof(long int); info = msg_get_by_id(msqid); if (!info) { syscall_errno = EINVAL; return -1; } if (!ipc_have_permissions(&(info->info.msg_perm), IPC_PERM_READ)) { syscall_errno = EACCES; return -1; } if (info->del) { syscall_errno = EIDRM; return -1; } msg = (sysv_msg_t *) llist_iterate_select(&(info->msgs), &msg_recv_iterator, (void *) msgtyp); if (!msg) { if (msgflg & IPC_NOWAIT) { syscall_errno = ENOMSG; return -1; } info->refs++; while (!msg) { if (semaphore_idown(info->rwaitsem)) { info->refs--; if (info->del && !info->refs) msg_do_delete(info); syscall_errno = EINTR; return -1; } if (info->del) { info->refs--; if (!info->refs) msg_do_delete(info); syscall_errno = EIDRM; return -1; } msg = (sysv_msg_t *) llist_iterate_select(&(info->msgs), &msg_recv_iterator, (void *) msgtyp); } } if (msg->msize > msgsz) { if (msgflg & MSG_NOERROR) readsz = msgsz; else { info->refs--; syscall_errno = E2BIG; return -1; } } else readsz = msg->msize; llist_unlink((llist_t *) msg); info->info.msg_qnum--; info->used_bytes -= msg->msize; info->refs--; memcpy(msgp, msg->mtext, readsz); heapmm_free(msg->mtext, msg->msize); heapmm_free(msg, sizeof(sysv_msg_t)); info->info.msg_lrpid = scheduler_current_task->pid; info->info.msg_rtime = (time_t) system_time; semaphore_up(info->swaitsem); return (ssize_t) (readsz - sizeof(long int)); }
// Used to allow students to leave the bar once they are drunk, // and thus is called by the students. // When a student leaves the bar, he frees up a place for another student to enter. void leave_bar(){ semaphore_up(bouncer); }
int main(int argc, char **argv) { int server_fd, port_number, max_fd, file_descriptors[MAX_NUMBER_USERS], i; int temp_fd, select_result, timer_is_active = FALSE, status_code; char *validation; fd_set file_descriptor_set; check_incorrect_usage(argc, argv); set_log_method(argv); set_lock(); port_number = extract_port_number(argv); server_fd = create_server(port_number, MAX_NUMBER_USERS); log_message("Streams server created", LOG_INFO); register_signal_handlers(); for (i = 0; i < MAX_NUMBER_USERS; i++) { file_descriptors[i] = 0; } // -- SHARED MEMORY AND SEMAPHORES -- shmid = create_shared_memory(); shared_mem_ptr = attach_memory(shmid); init_semaphores(); log_message("Shared memory and semaphores created", LOG_DEBUG); // -- SERVER LOOP -- while (TRUE) { FD_ZERO(&file_descriptor_set); FD_SET(server_fd, &file_descriptor_set); max_fd = server_fd; for (i = 0; i < MAX_NUMBER_USERS; i++) { temp_fd = file_descriptors[i]; if (temp_fd > 0) { FD_SET(temp_fd, &file_descriptor_set); } if (temp_fd > max_fd) { max_fd = temp_fd; } } select_result = select(max_fd + 1, &file_descriptor_set, NULL, NULL, NULL); if (select_result < 0 && errno != EINTR) { log_error("Select call error", LOG_WARNING, errno); continue; } if (FD_ISSET(server_fd, &file_descriptor_set)) { if ((temp_fd = accept(server_fd, NULL, 0)) < 0) { log_error("Could not accept incoming connection", LOG_ALERT, errno); exit(EXIT_FAILURE); } log_client_connection(temp_fd); for (i = 0; i < MAX_NUMBER_USERS; i++) { if (file_descriptors[i] != 0) continue; file_descriptors[i] = temp_fd; break; } } for (i = 0; i < MAX_NUMBER_USERS; i++) { temp_fd = file_descriptors[i]; if (!FD_ISSET(temp_fd, &file_descriptor_set)) continue; char *message = NULL; if ((message = (char *) calloc(MESSAGE_LENGTH, sizeof(char))) == NULL) { log_error("Memory allocation error", LOG_ALERT, errno); exit(EXIT_FAILURE); } if (recv(temp_fd, message, MESSAGE_LENGTH, 0) <= 0) // Disconnected { log_message("Client disconnected", LOG_INFO); close(temp_fd); file_descriptors[i] = 0; } else // Message sent to server { struct message_t mess=decode(message); if( (status_code = mess.type) == ERROR_MESSAGE) { continue; } if (get_game_phase() == REGISTER_PHASE) { if (status_code != 1) { // TODO Send message back to user? log_message("Currently register phase. User can only register", LOG_DEBUG); continue; } if (!timer_is_active) { log_message("Starting register timer", LOG_DEBUG); alarm(WAIT_TIME); timer_is_active = TRUE; } char *new_user = (char *) malloc(MAX_ARRAY_SIZE * sizeof(char)); sprintf(new_user, "User '%s' asks for registration. Adding user in memory.", (char *) mess.payload); log_message(new_user, LOG_INFO); // Add a player to the shared memory semaphore_down(SEMAPHORE_ACCESS); strncpy(shared_mem_ptr->players->name, (char *) mess.payload, strlen(mess.payload)); shared_mem_ptr->players[i].fd = temp_fd; shared_mem_ptr->players[i].score = 15; // TODO A supprimer semaphore_up(SEMAPHORE_ACCESS); validation = encode(VALID_REGISTRATION, "1"); send(temp_fd, validation, strlen(validation), 0); } else // GAME PHASE { log_message("Game phase. Not yet implemented.", LOG_INFO); } } } } return 0; }
/*** UP operation on a semaphore ***/ void _0x94_semaphore_up(void) { uint8_t key = (uint8_t)current_process->cpu.ebx; semaphore_up(key,current_process); current_process->state = READY; }