Example #1
0
File: mdm-top.c Project: cklin/mdm
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);
  }
}
Example #2
0
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;
        }
    }
}
Example #3
0
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;
}