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); }
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); }
/* 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); }
static void boxc_sent_push(Boxc *conn, Msg *m) { Octstr *os; char id[UUID_STR_LEN + 1]; if (conn->is_wap || !conn->sent || !m || msg_type(m) != sms) return; uuid_unparse(m->sms.id, id); os = octstr_create(id); dict_put(conn->sent, os, msg_duplicate(m)); semaphore_down(conn->pending); octstr_destroy(os); }
void* cupboy_work(){ while(1){ semaphore_down(cupboy_lk); int i; int k=dirty_cups_count(); for(i=0; i<k; i++){ struct Cup* cup=wash_dirty(); sleep(1); add_clean_cup(cup); printf(fileOut, "Cup boy added clean cup %d\n", cup->id); } } return 0; }
/* 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 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(); } }
bool lock_acquire(Lock *lock, int64_t timeout) { assert(semaphore_value(&lock->sema) <= 1); return semaphore_down(&lock->sema, 1, timeout); }
/*** DOWN operation on a semaphore ***/ void _0x94_semaphore_down(void) { uint8_t key = (uint8_t)current_process->cpu.ebx; if (semaphore_down(key,current_process)) // obtained current_process->state = READY; }
// Used to allow students to enter the bar, and thus is // called by the students. If the bar is full (the semaphore’s value is 0), // the student should wait until another student leaves the bar and frees up space. void enter_bar(){ semaphore_down(bouncer); }
void enter_bar() { semaphore_down(bouncer); entered_counter++; }
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; }