/** * Atomically wait for the semaphore to become non-zero (if needed), * then decrements it. */ void vlc_sem_wait (vlc_sem_t *sem) { int val; #if defined(__APPLE__) if (likely(semaphore_wait(*sem) == KERN_SUCCESS)) return; val = EINVAL; #else do if (likely(sem_wait (sem) == 0)) return; while ((val = errno) == EINTR); #endif VLC_THREAD_ASSERT ("locking semaphore"); }
void _dispatch_thread_semaphore_wait(_dispatch_thread_semaphore_t sema) { #if USE_MACH_SEM semaphore_t s4 = (semaphore_t)sema; kern_return_t kr; do { kr = semaphore_wait(s4); } while (slowpath(kr == KERN_ABORTED)); DISPATCH_SEMAPHORE_VERIFY_KR(kr); #elif USE_POSIX_SEM sem_t s4 = (sem_t)sema; int ret; do { ret = sem_wait(&s4); } while (slowpath(ret != 0)); DISPATCH_SEMAPHORE_VERIFY_RET(ret); #endif }
thread_t *thread_new_sized(const char *name, size_t work_queue_capacity) { assert(name != NULL); assert(work_queue_capacity != 0); thread_t *ret = osi_calloc(sizeof(thread_t)); if (!ret) goto error; ret->reactor = reactor_new(); if (!ret->reactor) goto error; ret->work_queue = fixed_queue_new(work_queue_capacity); if (!ret->work_queue) goto error; // Start is on the stack, but we use a semaphore, so it's safe struct start_arg start; start.start_sem = semaphore_new(0); if (!start.start_sem) goto error; strncpy(ret->name, name, THREAD_NAME_MAX); start.thread = ret; start.error = 0; pthread_create(&ret->pthread, NULL, run_thread, &start); semaphore_wait(start.start_sem); semaphore_free(start.start_sem); if (start.error) goto error; return ret; error:; if (ret) { fixed_queue_free(ret->work_queue, osi_free); reactor_free(ret->reactor); } osi_free(ret); return NULL; }
inline int fast_sendrecv_m (task_id dst_id, u32 arg1, u32 arg2, u32 *r_arg1, u32 *r_arg2) { quest_tss *src = lookup_TSS (str ()); quest_tss *dst = lookup_TSS (dst_id); semaphore_wait (&dst->Msem, 1, -1); dst->M[0] = arg1; dst->M[1] = arg2; semaphore_signal (&src->Msem, 1); ltr (dst_id); asm volatile ("call _sw_ipc" :"+S" (src), "+D" (dst) : :"eax", "ebx", "ecx", "edx", "cc", "memory"); /* after _sw_ipc dst and src are swapped */ *r_arg1 = dst->M[0]; *r_arg2 = dst->M[1]; return 0; }
int fprintf(FILE *fp, const char *fmt, ...) { kern_return_t kern_res; va_list ap; if (!_init) { _init++; MACH_CALL(semaphore_create(mach_task_self(), &lock, SYNC_POLICY_FIFO, 1), kern_res); } MACH_CALL(semaphore_wait(lock), kern_res); va_start(ap, fmt); vfprintf(fp, fmt, ap); va_end(ap); MACH_CALL(semaphore_signal(lock), kern_res); }
message_t *msg_receive(void) { message_t *msg = NULL; const uint32_t pid = proc_ctrl_get_curr_pid(); if (0 < msg_list[pid].nbr_in_que) { // Critical region starts... semaphore_wait(&g_mutex_msg_list); msg = msg_list[pid].next_msg; msg_list[pid].next_msg = msg_list[pid].next_msg->next_msg; msg_list[pid].nbr_in_que -= 1; // Critical regions ends... semaphore_signal(&g_mutex_msg_list); } return msg; }
DECLARE_TEST( semaphore, initialize ) { semaphore_t sem; semaphore_initialize( &sem, 0 ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 1 ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); semaphore_initialize( &sem, 2 ); EXPECT_TRUE( semaphore_wait( &sem ) ); EXPECT_TRUE( semaphore_try_wait( &sem, 100 ) ); EXPECT_FALSE( semaphore_try_wait( &sem, 100 ) ); semaphore_destroy( &sem ); return 0; }
enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout) { if(i2c_nr_stages == 0) return I2C_ERROR; i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_SEMAPHORE | BM_APB_CHx_CMD_IRQONCMPLT; BF_CLR(I2C_CTRL1, ALL_IRQ); imx233_dma_reset_channel(APB_I2C); imx233_icoll_enable_interrupt(INT_SRC_I2C_DMA, true); imx233_icoll_enable_interrupt(INT_SRC_I2C_ERROR, true); imx233_dma_enable_channel_interrupt(APB_I2C, true); imx233_dma_start_command(APB_I2C, &i2c_stage[0].dma); enum imx233_i2c_error_t ret; if(semaphore_wait(&i2c_sema, timeout) == OBJ_WAIT_TIMEDOUT) { imx233_dma_reset_channel(APB_I2C); imx233_i2c_reset(); ret = I2C_TIMEOUT; } else if(BF_RD(I2C_CTRL1, MASTER_LOSS_IRQ)) ret = I2C_MASTER_LOSS; else if(BF_RD(I2C_CTRL1, NO_SLAVE_ACK_IRQ)) { /* the core doesn't like this error, this is a workaround to prevent lock up */ #if IMX233_SUBTARGET >= 3780 BF_SET(I2C_CTRL1, CLR_GOT_A_NAK); #endif imx233_dma_reset_channel(APB_I2C); imx233_i2c_reset(); ret = I2C_NO_SLAVE_ACK; } else if(BF_RD(I2C_CTRL1, EARLY_TERM_IRQ)) ret = I2C_SLAVE_NAK; else ret = imx233_i2c_finalize(); /* sleep */ BF_SET(I2C_CTRL0, CLKGATE); mutex_unlock(&i2c_mutex); return ret; }
static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) { if (size > 0x10) RET_ERR(0); mmc_discard_irq(); SDCI_DMASIZE = size; SDCI_DMACOUNT = 1; SDCI_DMAADDR = dest; SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST; commit_discard_dcache(); PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG) | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), NULL, CEATA_COMMAND_TIMEOUT), 2, 1); if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2); PASS_RC(mmc_dsta_check_data_success(), 2, 3); return 0; }
int usb_drv_send(int ep, void *ptr, int len) { logf("usb_drv_send(%d,%x,%d): ", ep, (int)ptr, len); ep &= 0x7f; if (ep == 0 && got_set_configuration) { got_set_configuration = 0; if (len != 0) panicf("usb_drv_send: GSC, but len!=0"); /* Tell the HW we handled the request */ USB_DEV_CTRL |= USB_DEV_CTRL_APCSR_DONE; return 0; } ep_send(ep, ptr, len); if (semaphore_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT) logf("send timed out!\n"); return endpoints[ep][0].rc; }
static void *timer_func(void *arg) { timer_thread = mach_thread_self(); timer_thread_active = true; while (timer_thread_active) { clock_sleep(system_clock, TIME_ABSOLUTE, wakeup_time, NULL); semaphore_wait(wakeup_time_sem); tm_time_t system_time; timer_current_time(system_time); if (timer_cmp_time(wakeup_time, system_time) < 0) { wakeup_time = wakeup_time_max; SetInterruptFlag(INTFLAG_TIMER); TriggerInterrupt(); } semaphore_signal(wakeup_time_sem); } return NULL; }
/******************************************************************************* Name : EnterCriticalSection Description : Used to protect critical sections of Init/Open/Close/Term Parameters : None Assumptions : Limitations : Returns : Nothing *******************************************************************************/ static void EnterCriticalSection(void) { static BOOL InstancesAccessControlInitialized = FALSE; #if !defined(ST_OSLINUX) task_lock(); #endif if (!InstancesAccessControlInitialized) { InstancesAccessControlInitialized = TRUE; InstancesAccessControl_p = semaphore_create_fifo(1); } #if !defined(ST_OSLINUX) task_unlock(); #endif semaphore_wait(InstancesAccessControl_p); }
bool lua_acquire_execution_right(lua_t* env, bool force) { uint64_t self = thread_id(); if (atomic_load64(&env->executing_thread) == self) { ++env->executing_count; return true; } if (force) { semaphore_wait(&env->execution_right); atomic_store64(&env->executing_thread, self); FOUNDATION_ASSERT(env->executing_count == 0); ++env->executing_count; return true; } if (semaphore_try_wait(&env->execution_right, 0)) { atomic_store64(&env->executing_thread, self); FOUNDATION_ASSERT(env->executing_count == 0); ++env->executing_count; return true; } return false; }
void handler() { int i; for(i=0; i < 5; i++) { /* If you remove this protection, you should be able to see different * out of every time you run this program. With this protection, you * should always be able to see result to be 151402.656521 */ semaphore_wait(counter_mutex); /* down semaphore */ /* START CRITICAL REGION */ int j; for (j = 0; j < 1000; j++) { result = result + sin(counter) * tan(counter); } counter++; /* END CRITICAL REGION */ semaphore_signal(counter_mutex); /* up semaphore */ } mythread_exit(); /* exit thread */ }
uint32_t msg_send(message_t *msg) { uint32_t ret = 0; ASSERT(NULL != msg); // ASSERT if the msg not pointing on the heap ASSERT(PID_IDLE != msg->receiver); ASSERT(HIGH_PID >= msg->receiver); ASSERT(msg_none_1 < msg->id && msg->id < msg_none_2); ret = msg->receiver; // Critical region starts... semaphore_wait(&g_mutex_msg_list); if (0 == msg_list[msg->receiver].nbr_in_que) { msg_list[msg->receiver].next_msg = msg; msg_list[msg->receiver].last_msg = msg; } else { msg_list[msg->receiver].last_msg->next_msg = msg; msg_list[msg->receiver].last_msg = msg; } msg_list[msg->receiver].nbr_in_que += 1; msg->next_msg = NULL; // semaphore_signal will generate a context switch. Make sure that the // receiving process is in state ready. if (msg->receiver != proc_ctrl_get_curr_pid()) { proc_ctrl_change_state(msg->receiver, ready); } // Critical regions ends... semaphore_signal(&g_mutex_msg_list); msg = NULL; return ret; }
thread_t *thread_new(const char *name) { assert(name != NULL); // Start is on the stack, but we use a semaphore, so it's safe thread_t *ret = calloc(1, sizeof(thread_t)); if (!ret) goto error; ret->reactor = reactor_new(); if (!ret->reactor) goto error; ret->work_queue = fixed_queue_new(WORK_QUEUE_CAPACITY); if (!ret->work_queue) goto error; struct start_arg start; start.start_sem = semaphore_new(0); if (!start.start_sem) goto error; strncpy(ret->name, name, THREAD_NAME_MAX); start.thread = ret; start.error = 0; pthread_create(&ret->pthread, NULL, run_thread, &start); semaphore_wait(start.start_sem); semaphore_free(start.start_sem); if (start.error) goto error; return ret; error:; if (ret) { fixed_queue_free(ret->work_queue, free); reactor_free(ret->reactor); } free(ret); return NULL; }
char* file_queue_get() { char* result; semaphore_wait(&used_slots); mutex_lock(&queue_mutex); if (queue_head == queue_tail) // queue is empty { result = NULL; } else { result = file_queue[queue_head].path; queue_head = (queue_head + 1) % (MAX_QUEUED_FILES + 1); } mutex_unlock(&queue_mutex); semaphore_release(&unused_slots); return result; }
static int _usb_drv_send(int endpoint, void *ptr, int length, bool block) { struct endpoint_t *ep; int ep_num = EP_NUM(endpoint); if (ep_num == 0) ep = &ctrlep[DIR_IN]; else ep = &endpoints[ep_num]; ep->buf = ptr; ep->len = ep->cnt = length; if (block) ep->block = true; else ep->block = false; switch (ep->type) { case USB_ENDPOINT_XFER_CONTROL: ctr_write(); break; case USB_ENDPOINT_XFER_BULK: blk_write(ep_num); break; case USB_ENDPOINT_XFER_INT: int_write(ep_num); break; } if (block) /* wait for transfer to end */ semaphore_wait(&ep->complete, TIMEOUT_BLOCK); return 0; }
/** * This is the main system call function. It takes an interrupt stack frame * and decodes which interrupt number generated the system call. This number * is used to decode which system call was called. * * The stack frame is used to both pass and receive information from the * system call. * ECX: On completion of the system call ecx is populated with the return * value * EAX: Contains the system call number * EBX: Contains the ptr to the first of the parameters * * @param frame Ptr to a handler_stack_frame struture * @return SUCCESS on success or FAILURE if something goes wrong */ int system_call( struct handler_stack_frame* frame ) { int system_call_number; char** system_call_params; int* system_call_result; system_call_result = (int*)frame->ecx; system_call_params = (char**)frame->ebx; system_call_number = frame->eax; switch( system_call_number ) { case SYS_SEMA_CREATE: *system_call_result = semaphore_create( (sema_handle*)system_call_params[0], (int)system_call_params[1] ); break; case SYS_SEMA_WAIT: *system_call_result = semaphore_wait( (int)system_call_params[0] ); break; case SYS_SEMA_SIGNAL: *system_call_result = semaphore_signal( (int)system_call_params[0] ); break; case SYS_SEMA_DESTROY: *system_call_result = semaphore_destroy( (int)system_call_params[0] ); break; case SYS_THREAD_EXIT: *system_call_result = sys_thread_exit(); break; case SYS_MSLEEP: *system_call_result = sys_msleep((uint)system_call_params[0] ); break; default: *system_call_result = FAILURE; break; } return SUCCESS; }
/* * Block forever waiting for EVENT to be signalled, * or timeout after timeout (ms) have expired * set timeout to EMBX_TIMEOUT_INFINITE to wait forever * * Returns EMBX_SUCCESS if signalled, EMBX_SYSTEM_TIMEOUT otherwise */ EMBX_ERROR EMBX_OS_EventWaitTimeout(EMBX_EVENT ev, unsigned long timeout) { int res; osclock_t time; EMBX_Assert(ev); if (timeout != EMBX_TIMEOUT_INFINITE) { /* OS21 semaphore timeout takes an absolute time value * so we calculate that here */ time = time_plus(time_now(), (timeout*time_ticks_per_sec())/1000); res = semaphore_wait_timeout(ev->event, &time); } else /* Infinite wait */ res = semaphore_wait(ev->event); if (res == OS21_FAILURE) return EMBX_SYSTEM_TIMEOUT; return EMBX_SUCCESS; }
int printf(const char *fmt, ...) { kern_return_t kern_res; va_list ap; if (!_init) { _init++; MACH_CALL(semaphore_create(mach_task_self(), &lock, SYNC_POLICY_FIFO, 1), kern_res); } MACH_CALL(semaphore_wait(lock), kern_res); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); MACH_CALL(semaphore_signal(lock), kern_res); if (kern_res == KERN_SUCCESS) return 0; else return -1; }
void hotplug_task_fn(void *val) { while(1) { semaphore_wait(hotplug_sem); switch(currentDisplayStatus) { case STM_DISPLAY_NEEDS_RESTART: if(!silent_hotplug) printf("HDMI TV Starting Link\n"); if(stm_display_output_start(pHDMI, pModeLine, STM_OUTPUT_STD_CEA861C)<0) { if(!silent_hotplug) printf("Unable to start HDMI\n"); } break; case STM_DISPLAY_CONNECTED: if(!silent_hotplug) printf("HDMI TV Successfully Connected\n"); break; case STM_DISPLAY_DISCONNECTED: if(!silent_hotplug) printf("HDMI TV Disconnected\n"); stm_display_output_stop(pHDMI); break; } } }
/*! * @brief IO system initialization. * When user wants to start up the codec system, * this function call is needed, to open the codec device, * map the register into user space, * get the working buffer/code buffer/parameter buffer, * download the firmware, and then set up the interrupt signal path. * * @param callback vpu interrupt callback. * * @return * @li 0 System initialization success. * @li -1 System initialization failure. */ int IOSystemInit(void *callback) { int ret; /* Exit directly if already initialized */ if (vpu_fd > 0) { vpu_active_num++; return 0; } ret = get_system_rev(); if (ret == -1) { err_msg("Error: Unable to obtain system rev information\n"); return -1; } vpu_fd = open("/dev/mxc_vpu", O_RDWR); if (vpu_fd < 0) { err_msg("Can't open /dev/mxc_vpu: %s\n", strerror(errno)); return -1; } vpu_shared_mem = vpu_semaphore_open(); if (vpu_shared_mem == NULL) { err_msg("Error: Unable to open vpu shared memory file\n"); close(vpu_fd); vpu_fd = -1; return -1; } if (!semaphore_wait(vpu_semap, API_MUTEX)) { err_msg("Error: Unable to get mutex\n"); close (vpu_fd); vpu_fd = -1; return -1; } vpu_reg_base = (unsigned long)mmap(NULL, BIT_REG_MARGIN, PROT_READ | PROT_WRITE, MAP_SHARED, vpu_fd, 0); if ((void *)vpu_reg_base == MAP_FAILED) { err_msg("Can't map register\n"); close(vpu_fd); vpu_fd = -1; semaphore_post(vpu_semap, API_MUTEX); return -1; } vpu_active_num++; IOClkGateSet(true); #ifdef BUILD_FOR_ANDROID unsigned long va_addr; /* Special handle the bit work buffer, which reserved in vpu driver probe */ bit_work_addr.size = TEMP_BUF_SIZE + PARA_BUF_SIZE + CODE_BUF_SIZE + PARA_BUF2_SIZE; if (_IOGetPhyMem(VPU_IOC_GET_WORK_ADDR, &bit_work_addr) < 0) { err_msg("Get bitwork address failed!\n"); goto err; } va_addr = (unsigned long)mmap(NULL, bit_work_addr.size, PROT_READ | PROT_WRITE, MAP_SHARED, vpu_fd, bit_work_addr.phy_addr); if ((void *)va_addr == MAP_FAILED) { bit_work_addr.virt_uaddr = 0; goto err; } bit_work_addr.virt_uaddr = va_addr; #else bit_work_addr.size = TEMP_BUF_SIZE + PARA_BUF_SIZE + CODE_BUF_SIZE + PARA_BUF2_SIZE; if (_IOGetPhyMem(VPU_IOC_GET_WORK_ADDR, &bit_work_addr) < 0) { err_msg("Get bitwork address failed!\n"); goto err; } if (IOGetVirtMem(&bit_work_addr) == -1) goto err; #endif UnlockVpu(vpu_semap); return 0; err: err_msg("Error in IOSystemInit()"); UnlockVpu(vpu_semap); IOSystemShutdown(); return -1; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_THREAD) { int status; WINPR_THREAD* thread; void* thread_status = NULL; if (dwMilliseconds != INFINITE) printf("WaitForSingleObject: timeout not implemented for thread wait\n"); thread = (WINPR_THREAD*) Object; status = pthread_join(thread->thread, &thread_status); if (status != 0) printf("WaitForSingleObject: pthread_join failure: %d\n", status); } else if (Type == HANDLE_TYPE_MUTEX) { if (dwMilliseconds != INFINITE) printf("WaitForSingleObject: timeout not implemented for mutex wait\n"); pthread_mutex_lock((pthread_mutex_t*) Object); } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) return FALSE; } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else { printf("WaitForSingleObject: unknown handle type %d\n", Type); } return WAIT_OBJECT_0; }
int main(int argc, char **argv) { int i, port, pid, listenfd, socketfd, hit, consumers; socklen_t length; static struct sockaddr_in cli_addr; /* static = initialised to zeros */ static struct sockaddr_in serv_addr; /* static = initialised to zeros */ #if OperationMode == 2 if (argc < 5 || argc > 5 || !strcmp(argv[1], "-?")) { printf("\n\nhint: ./tftps Port-Number Top-Directory Consumer-Threads Buffer-Size\n\n""\ttftps is a small and very safe mini ftp server\n""\tExample: ./tftps 8181 ./fileDir \n\n"); exit(0); } consumers = atoi(argv[3]); initConsumerStruct(&shared, (size_t) atoi(argv[4])); #else if (argc < 3 || argc > 3 || !strcmp(argv[1], "-?")) { printf("\n\nhint: ./tftps Port-Number Top-Directory\n\n""\ttftps is a small and very safe mini ftp server\n""\tExample: ./tftps 8181 ./fileDir \n\n"); exit(0); } #endif port = atoi(argv[1]); defaultPath = argv[2]; if (chdir(defaultPath) == -1) { printf("ERROR: Can't Change to directory %s\n", argv[2]); exit(4); } printf("LOG tftps starting %s - pid %d\n", argv[1], getpid()); /* setup the network socket */ if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("ERROR system call - setup the socket\n"); if (port < 0 || port > 60000) printf("ERROR Invalid port number (try 1->60000)\n"); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); if (bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) printf("ERROR system call - bind error\n"); if (listen(listenfd, 64) < 0) printf("ERROR system call - listen error\n"); #if OperationMode == 2 pthread_t idC; int index = 0, item; #if ApplePositive semaphore_create(mach_task_self(), &shared.full, SYNC_POLICY_FIFO, 0); semaphore_create(mach_task_self(), &shared.empty, SYNC_POLICY_FIFO, shared.buffSize); #else sem_t *semFull = sem_open("/semFull", O_CREAT, 0644, 0); sem_t *semEmpty = sem_open("/semEmpty", O_CREAT, 0644, shared.buffSize); shared.full = *semFull; shared.empty = *semEmpty; #endif pthread_mutex_init(&shared.mutex, NULL); /*create a new Consumer*/ for(index=0; index<consumers; index++) { pthread_create(&idC, NULL, Consumer, (void*)&index); } struct sigaction act; act.sa_handler = &onAlarm; act.sa_flags = SA_RESTART; // Restart interrupted system calls sigaction(SIGALRM, &act, NULL); alarm(30); #endif // Main LOOP for (hit = 1 ;; hit++) { length = sizeof(cli_addr); /* block waiting for clients */ socketfd = accept(listenfd, (struct sockaddr *) &cli_addr, &length); if (socketfd < 0) printf("ERROR system call - accept error\n"); else { #if OperationMode #if OperationMode == 1 pthread_t thread_id; THREAD_ARGS *args = malloc(sizeof(THREAD_ARGS)); int * sockAUX = (int *) malloc(sizeof(int *)); *sockAUX = socketfd; args->fd = sockAUX; args->hit = hit; if (args != NULL) { if (pthread_create(&thread_id, NULL, &attendFTP, args)) { perror("could not create thread"); return 1; } } #else item = socketfd; #if ApplePositive semaphore_wait(shared.empty); #else sem_wait(&shared.empty); #endif pthread_mutex_lock(&shared.mutex); shared.buff[shared.in] = item; pthread_mutex_unlock(&shared.mutex); shared.in = (shared.in + 1) % shared.buffSize; #if ApplePositive semaphore_signal(shared.full); #else sem_post(&shared.full); #endif #endif #else pid = fork(); if(pid==0) { ftp(socketfd, hit); exit(0); } else { //Temos de fechar o socketfd para que seja apenas a child a tratar dos pedidos, caso contrário iria ficar aqui pendurado close(socketfd); signal(pid, SIGCHLD); } #endif } } }
/** * Placed at the head of all monitor functions, this enters a monitor * or waits if it is occupied. */ void monitor_enter(monitor_t *monitor) { semaphore_wait(monitor->sem_id, MUTEX_SEM); }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) { fprintf(stderr, "WaitForSingleObject failed: invalid hHandle.\n"); return WAIT_FAILED; } if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { struct timespec timeout; /* pthread_timedjoin_np returns ETIMEDOUT in case the timeout is 0, * so set it to the smallest value to get a proper return value. */ if (dwMilliseconds == 0) dwMilliseconds ++; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else status = pthread_join(thread->thread, &thread_status); if (status != 0) { fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); } if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_PROCESS) { WINPR_PROCESS* process; process = (WINPR_PROCESS*) Object; if (waitpid(process->pid, &(process->status), 0) != -1) { fprintf(stderr, "WaitForSingleObject: waitpid failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } process->dwExitCode = (DWORD) process->status; } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; if (dwMilliseconds != INFINITE) { int status; struct timespec timeout; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_mutex_timedlock(&mutex->mutex, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) { fprintf(stderr, "WaitForSingleObject: semaphore read failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) { if (status == -1) { if (errno == ETIMEDOUT) return WAIT_TIMEOUT; fprintf(stderr, "WaitForSingleObject: timer read() failure [%d] %s\n", errno, strerror(errno)); } else { fprintf(stderr, "WaitForSingleObject: timer read() failure - incorrect number of bytes read"); } return WAIT_FAILED; } } else { fprintf(stderr, "WaitForSingleObject: invalid timer file descriptor\n"); return WAIT_FAILED; } #else fprintf(stderr, "WaitForSingleObject: file descriptors not supported\n"); return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int fd; int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; if (fd == -1) { fprintf(stderr, "WaitForSingleObject: invalid pipe file descriptor\n"); return WAIT_FAILED; } FD_ZERO(&rfds); FD_SET(fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) { return WAIT_TIMEOUT; } } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }
void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg, Addr stacksize, Addr flags, Addr sp) { vki_sigset_t blockall; ThreadState *tst = (ThreadState *)func_arg; VexGuestAMD64State *vex = &tst->arch.vex; // VG_(printf)("pthread_hijack pthread %p, machthread %p, func %p, arg %p, stack %p, flags %p, stack %p\n", self, kport, func, func_arg, stacksize, flags, sp); // Wait for parent thread's permission. // The parent thread holds V's lock on our behalf. semaphore_wait(tst->os_state.child_go); /* Start the thread with all signals blocked. VG_(scheduler) will set the mask correctly when we finally get there. */ VG_(sigfillset)(&blockall); VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, NULL); // Set thread's registers // Do this FIRST because some code below tries to collect a backtrace, // which requires valid register data. LibVEX_GuestAMD64_initialise(vex); vex->guest_RIP = pthread_starter; vex->guest_RDI = self; vex->guest_RSI = kport; vex->guest_RDX = func; vex->guest_RCX = tst->os_state.func_arg; vex->guest_R8 = stacksize; vex->guest_R9 = flags; vex->guest_RSP = sp; // Record thread's stack and Mach port and pthread struct tst->os_state.pthread = self; tst->os_state.lwpid = kport; record_named_port(tst->tid, kport, MACH_PORT_RIGHT_SEND, "thread-%p"); if ((flags & 0x01000000) == 0) { // kernel allocated stack - needs mapping Addr stack = VG_PGROUNDUP(sp) - stacksize; tst->client_stack_highest_word = stack+stacksize; tst->client_stack_szB = stacksize; // pthread structure ML_(notify_core_and_tool_of_mmap)( stack+stacksize, pthread_structsize, VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_PRIVATE, -1, 0); // stack contents ML_(notify_core_and_tool_of_mmap)( stack, stacksize, VKI_PROT_READ|VKI_PROT_WRITE, VKI_MAP_PRIVATE, -1, 0); // guard page ML_(notify_core_and_tool_of_mmap)( stack-VKI_PAGE_SIZE, VKI_PAGE_SIZE, 0, VKI_MAP_PRIVATE, -1, 0); } else { // client allocated stack find_stack_segment(tst->tid, sp); } ML_(sync_mappings)("after", "pthread_hijack", 0); // DDD: should this be here rather than in POST(sys_bsdthread_create)? // But we don't have ptid here... //VG_TRACK ( pre_thread_ll_create, ptid, tst->tid ); // Tell parent thread's POST(sys_bsdthread_create) that we're done // initializing registers and mapping memory. semaphore_signal(tst->os_state.child_done); // LOCK IS GONE BELOW THIS POINT // Go! call_on_new_stack_0_1(tst->os_state.valgrind_stack_init_SP, 0, start_thread_NORETURN, (Word)tst); /*NOTREACHED*/ vg_assert(0); }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { #if HAVE_PTHREAD_GNU_EXT struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); #else fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__); assert(0); #endif } else status = pthread_join(thread->thread, &thread_status); if (status != 0) fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; #if HAVE_PTHREAD_GNU_EXT if (dwMilliseconds != INFINITE) { struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); pthread_mutex_timedlock(&mutex->mutex, &timeout); } else #endif { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) return WAIT_FAILED; } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) return WAIT_TIMEOUT; } else { return WAIT_FAILED; } #else return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; FD_ZERO(&rfds); FD_SET(pipe->clientfd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(pipe->clientfd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }
DISPATCH_NOINLINE static long _dispatch_group_wait_slow(dispatch_semaphore_t dsema, dispatch_time_t timeout) { long orig; again: // check before we cause another signal to be sent by incrementing // dsema->dsema_group_waiters if (dsema->dsema_value == dsema->dsema_orig) { return _dispatch_group_wake(dsema); } // Mach semaphores appear to sometimes spuriously wake up. Therefore, // we keep a parallel count of the number of times a Mach semaphore is // signaled (6880961). (void)dispatch_atomic_inc2o(dsema, dsema_group_waiters); // check the values again in case we need to wake any threads if (dsema->dsema_value == dsema->dsema_orig) { return _dispatch_group_wake(dsema); } #if USE_MACH_SEM mach_timespec_t _timeout; kern_return_t kr; _dispatch_semaphore_create_port(&dsema->dsema_waiter_port); // From xnu/osfmk/kern/sync_sema.c: // wait_semaphore->count = -1; /* we don't keep an actual count */ // // The code above does not match the documentation, and that fact is // not surprising. The documented semantics are clumsy to use in any // practical way. The above hack effectively tricks the rest of the // Mach semaphore logic to behave like the libdispatch algorithm. switch (timeout) { default: do { uint64_t nsec = _dispatch_timeout(timeout); _timeout.tv_sec = (typeof(_timeout.tv_sec))(nsec / NSEC_PER_SEC); _timeout.tv_nsec = (typeof(_timeout.tv_nsec))(nsec % NSEC_PER_SEC); kr = slowpath(semaphore_timedwait(dsema->dsema_waiter_port, _timeout)); } while (kr == KERN_ABORTED); if (kr != KERN_OPERATION_TIMED_OUT) { DISPATCH_SEMAPHORE_VERIFY_KR(kr); break; } // Fall through and try to undo the earlier change to // dsema->dsema_group_waiters case DISPATCH_TIME_NOW: while ((orig = dsema->dsema_group_waiters)) { if (dispatch_atomic_cmpxchg2o(dsema, dsema_group_waiters, orig, orig - 1)) { return KERN_OPERATION_TIMED_OUT; } } // Another thread called semaphore_signal(). // Fall through and drain the wakeup. case DISPATCH_TIME_FOREVER: do { kr = semaphore_wait(dsema->dsema_waiter_port); } while (kr == KERN_ABORTED); DISPATCH_SEMAPHORE_VERIFY_KR(kr); break; } #elif USE_POSIX_SEM struct timespec _timeout; int ret; switch (timeout) { default: do { _timeout = _dispatch_timeout_ts(timeout); ret = slowpath(sem_timedwait(&dsema->dsema_sem, &_timeout)); } while (ret == -1 && errno == EINTR); if (!(ret == -1 && errno == ETIMEDOUT)) { DISPATCH_SEMAPHORE_VERIFY_RET(ret); break; } // Fall through and try to undo the earlier change to // dsema->dsema_group_waiters case DISPATCH_TIME_NOW: while ((orig = dsema->dsema_group_waiters)) { if (dispatch_atomic_cmpxchg2o(dsema, dsema_group_waiters, orig, orig - 1)) { errno = ETIMEDOUT; return -1; } } // Another thread called semaphore_signal(). // Fall through and drain the wakeup. case DISPATCH_TIME_FOREVER: do { ret = sem_wait(&dsema->dsema_sem); } while (ret == -1 && errno == EINTR); DISPATCH_SEMAPHORE_VERIFY_RET(ret); break; } #endif goto again; }