static int semu_search_with_addr(list_entry_t * list, uintptr_t addr) { list_entry_t *le = list; while ((le = list_next(le)) != list) { sem_undo_t *semu = le2semu(le, semu_link); if (semu->sem->addr == addr) return sem2semid(semu->sem); } return -1; }
int ipc_sem_init(int value) { assert(current->sem_queue != NULL); sem_undo_t *semu; if ((semu = semu_create(NULL, value)) == NULL) { return -E_NO_MEM; } sem_queue_t *sem_queue = current->sem_queue; down(&(sem_queue->sem)); list_add_after(&(sem_queue->semu_list), &(semu->semu_link)); up(&(sem_queue->sem)); return sem2semid(semu->sem); }
static int ipc_sem_find_or_init_with_address(uintptr_t addr, int value, int create) { assert(pls_read(current)->sem_queue != NULL); sem_queue_t *sem_queue = pls_read(current)->sem_queue; down(&(sem_queue->sem)); sem_t sem_id = semu_search_with_addr(&(sem_queue->semu_list), addr); up(&(sem_queue->sem)); if(sem_id != -1) return sem_id; if(!create) return -E_NO_MEM; sem_undo_t *semu; if((semu = semu_create_with_address(NULL, addr, value)) == NULL) { return -E_NO_MEM; } down(&(sem_queue->sem)); list_add_after(&(sem_queue->semu_list), &(semu->semu_link)); up(&(sem_queue->sem)); return sem2semid(semu->sem); }