static void end_run(pid_t pid, int status) { int index = find_run(pid); run *rptr = runs+index; if (status > 255) status = 255; switch (rptr->stage) { case STAGE_ISSUE: ac--; rptr->status = status; rptr->pc.state = ' '; if (status) { rptr-> stage = STAGE_ATTN; break; } case STAGE_ATTN: assert(status == 0); rptr->stage = STAGE_DONE; break; default: errx(6, "Job stage error (%d)", rptr->stage); } }
void text_itemizer::create_item_list() { /* This function iterates over direction runs in visual order and splits them if neccessary. * Split RTL runs are processed in reverse order to keep glyphs in correct order. * * logical 123 | 456789 * LTR visual 123 | 456789 * RTL visual 987654 | 321 * Glyphs within a single run are reversed by the shaper. */ output_.clear(); for (auto const& dir_run : direction_runs_) { unsigned position = dir_run.start; unsigned end = dir_run.end; std::list<text_item>::iterator rtl_insertion_point = output_.end(); // Find first script and format run format_run_list::const_iterator format_itr = find_run(format_runs_, position); script_run_list::const_iterator script_itr = find_run(script_runs_, position); while (position < end) { assert(script_itr != script_runs_.end()); assert(format_itr != format_runs_.end()); text_item item; item.start = position; position = std::min(script_itr->end, std::min(format_itr->end, end)); item.end = position; item.format = format_itr->data; item.script = script_itr->data; item.rtl = dir_run.data; if (dir_run.data == UBIDI_LTR) { output_.push_back(item); } else { rtl_insertion_point = output_.insert(rtl_insertion_point, item); } if (script_itr->end == position) ++script_itr; if (format_itr->end == position) ++format_itr; } } }
static int __noinstrument kfi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { unsigned long flags; struct kfi_run* run; struct kfi_run urun; struct kfi_entry* ulog; void** ufunc_list; int ufunc_list_size; switch (cmd) { case KFI_RESET: kfi_reset(); break; case KFI_NEW_RUN: if (verify_area(VERIFY_READ, (void *)arg, sizeof(struct kfi_run)) || verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct kfi_run))) return -EFAULT; if ((run = (struct kfi_run*)kmalloc(sizeof(struct kfi_run), GFP_KERNEL)) == NULL) return -ENOMEM; copy_from_user(&urun, (struct kfi_run*)arg, sizeof(struct kfi_run)); if (urun.num_entries > MAX_RUN_LOG_ENTRIES) { kfree(run); return -EINVAL; } *run = urun; run->id = next_run_id++; run->triggered = run->complete = 0; run->next_entry = 0; #ifdef KFI_DEBUG run->notfound = 0; memset(&run->filters.cnt, 0, sizeof(run->filters.cnt)); #endif run->next = NULL; urun = *run; run->log = (struct kfi_entry*) kmalloc(sizeof(struct kfi_entry) * run->num_entries, GFP_KERNEL); if (run->log == NULL) { kfree(run); return -ENOMEM; } memset(run->log, 0, sizeof(struct kfi_entry) * run->num_entries); if (urun.filters.func_list) { int size; if (urun.filters.func_list_size > MAX_FUNC_LIST_ENTRIES) { kfree(run->log); kfree(run); return -EINVAL; } size = urun.filters.func_list_size * sizeof(void*); if (verify_area(VERIFY_READ, (void *)urun.filters.func_list, size)) { kfree(run->log); kfree(run); return -EFAULT; } run->filters.func_list = (void**)kmalloc(size, GFP_KERNEL); if (run->filters.func_list == NULL) { kfree(run->log); kfree(run); return -ENOMEM; } copy_from_user(run->filters.func_list, urun.filters.func_list, size); } /* new run is ready, return it to user */ copy_to_user((struct kfi_run*)arg, &urun, sizeof(struct kfi_run)); /* tack it on */ local_irq_save(flags); if (!run_tail) { run_head = run_tail = run_curr = run; } else { if (run_curr == run_tail && run_curr->complete) run_curr = run; run_tail->next = run; run_tail = run; } local_irq_restore(flags); break; case KFI_START: local_irq_save(flags); run = run_curr; if (!run || run->complete || run->triggered) { local_irq_restore(flags); return -EINVAL; } run->triggered = 1; run->start_trigger.mark = update_usecs_since_boot(); run->start_trigger.type = TRIGGER_DEV; local_irq_restore(flags); if (put_user(run->id, (int *)arg)) return -EFAULT; break; case KFI_STOP: local_irq_save(flags); run = run_curr; if (!run || run->complete) { local_irq_restore(flags); return -EINVAL; } run->complete = 1; run->stop_trigger.mark = update_usecs_since_boot(); run->stop_trigger.type = TRIGGER_DEV; if (run->next != NULL) run_curr = run->next; local_irq_restore(flags); if (waitqueue_active(&kfi_wait)) wake_up_interruptible(&kfi_wait); if (put_user(run->id, (int *)arg)) return -EFAULT; break; case KFI_READ: case KFI_READ_CURR: if (verify_area(VERIFY_READ, (void *)arg, sizeof(struct kfi_run)) || verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct kfi_run))) return -EFAULT; copy_from_user(&urun, (struct kfi_run*)arg, sizeof(struct kfi_run)); local_irq_save(flags); run = (cmd == KFI_READ_CURR) ? run_curr : find_run(urun.id); if (!run) { local_irq_restore(flags); return -EINVAL; } if (urun.log != NULL) { if (urun.num_entries < run->num_entries) { local_irq_restore(flags); return -EINVAL; } if (!run->complete) { local_irq_restore(flags); if (file->f_flags & O_NONBLOCK) return -EAGAIN; while (!run->complete) { interruptible_sleep_on(&kfi_wait); if (signal_pending(current)) return -ERESTARTSYS; } local_irq_save(flags); } } ufunc_list_size = urun.filters.func_list_size; // save user pointers ulog = urun.log; ufunc_list = urun.filters.func_list; urun = *run; // copy run // restore user pointers urun.log = ulog; urun.filters.func_list = ufunc_list; urun.next = NULL; local_irq_restore(flags); copy_to_user((void*)arg, &urun, sizeof(struct kfi_run)); if (urun.log != NULL) { int size = run->next_entry * sizeof(struct kfi_entry); if (verify_area(VERIFY_WRITE, (void*)urun.log, size)) return -EFAULT; copy_to_user((void*)urun.log, run->log, size); } if (ufunc_list != NULL && run->filters.func_list != NULL) { int size; if (ufunc_list_size < run->filters.func_list_size) return -EINVAL; size = run->filters.func_list_size * sizeof(void*); if (verify_area(VERIFY_WRITE, ufunc_list, size)) return -EFAULT; copy_to_user(ufunc_list, run->filters.func_list, size); } break; case KFI_READ_TIMER: if (put_user(update_usecs_since_boot(), (unsigned long *)arg)) return -EFAULT; break; default: return -EINVAL; } return 0; }