Ejemplo n.º 1
0
void UmlActivityAction::write_end(FileOut & out, bool dontclose) {
  out << ">\n";
  out.indent(+1);
  
  Q3CString s = constraint();
  
  if (! s.isEmpty()) {
    out.indent();
    out << "<ownedRule xmi:type=\"uml:Constraint\"";
    out.id_prefix(this, "CONSTRAINT_");
    out.ref(this, "constrainedElement");
    out << ">\n";
    out.indent();
    out << "\t<specification xmi:type=\"uml:OpaqueExpression\"";
    out.id_prefix(this, "CSPEC_");
    out << ">\n";
    out.indent();
    out << "\t\t<body>";
    out.quote(s);
    out << "</body>\n";
    out.indent();
    out << "\t</specification>\n";
    out.indent();
    out << "</ownedRule>\n";
  }
  
  write_description_properties(out);

  switch (_lang) {
  case Uml:
    write_condition(out, preCondition(), TRUE);
    write_condition(out, postCondition(), FALSE);
    break;
  case Cpp:
    write_condition(out, cppPreCondition(), TRUE);
    write_condition(out, cppPostCondition(), FALSE);
    break;
  default:
    // java
    write_condition(out, javaPreCondition(), TRUE);
    write_condition(out, javaPostCondition(), FALSE);
  }

  const Q3PtrVector<UmlItem> ch = children();
  unsigned n = ch.size();
  
  for (unsigned i = 0; i != n; i += 1)
    ch[i]->write(out);

  write_incoming_flows(out);
  
  if (!dontclose)
    write_close(out);
}
Ejemplo n.º 2
0
Archivo: osprd.c Proyecto: freehan/lab2
/*
 * osprd_ioctl(inode, filp, cmd, arg)
 *   Called to perform an ioctl on the named file.
 */
int osprd_ioctl(struct inode *inode, struct file *filp,
		unsigned int cmd, unsigned long arg)
{
	osprd_info_t *d = file2osprd(filp);	// device info
	int r = 0;			// return value: initially 0

	// is file open for writing?
	int filp_writable = (filp->f_mode & FMODE_WRITE) != 0;

	// This line avoids compiler warnings; you may remove it.
	(void) filp_writable, (void) d;

	// Set 'r' to the ioctl's return value: 0 on success, negative on error
    
    
    
	if (cmd == OSPRDIOCACQUIRE) {

		// EXERCISE: Lock the ramdisk.
		//
		// If *filp is open for writing (filp_writable), then attempt
		// to write-lock the ramdisk; otherwise attempt to read-lock
		// the ramdisk.
		//
                // This lock request must block using 'd->blockq' until:
		// 1) no other process holds a write lock;
		// 2) either the request is for a read lock, or no other process
		//    holds a read lock; and
		// 3) lock requests should be serviced in order, so no process
		//    that blocked earlier is still blocked waiting for the
		//    lock.
		//
		// If a process acquires a lock, mark this fact by setting
		// 'filp->f_flags |= F_OSPRD_LOCKED'.  You also need to
		// keep track of how many read and write locks are held:
		// change the 'osprd_info_t' structure to do this.
		//
		// Also wake up processes waiting on 'd->blockq' as needed.
		//
		// If the lock request would cause a deadlock, return -EDEADLK.
		// If the lock request blocks and is awoken by a signal, then
		// return -ERESTARTSYS.
		// Otherwise, if we can grant the lock request, return 0.

		// 'd->ticket_head' and 'd->ticket_tail' should help you
		// service lock requests in order.  These implement a ticket
		// order: 'ticket_tail' is the next ticket, and 'ticket_head'
		// is the ticket currently being served.  You should set a local
		// variable to 'd->ticket_head' and increment 'd->ticket_head'.
		// Then, block at least until 'd->ticket_tail == local_ticket'.
		// (Some of these operations are in a critical section and must
		// be protected by a spinlock; which ones?)

		// Your code here (instead of the next two lines).
        
        int my_ticket = 0;              ///keep track of my ticket
        osp_spin_lock(&d->mutex);
        my_ticket = d->ticket_head++;
        osp_spin_unlock(&d->mutex);
        
        d->pid_tracker[my_ticket%MAX_MEM_SIZE] = current->pid;
        
#ifdef DEBUG
        eprintk("Handling ACQUIRE, my_ticket is %d\n",my_ticket);
        eprintk("Current pid is :%d\n", current->pid);
#endif
        
        //check self deadlock
        osp_spin_lock(&d->mutex);
        int run_count = d->read_count + d->write_count;
        int index = (d->ticket_tail - 1)%MAX_MEM_SIZE;
        osp_spin_unlock(&d->mutex);
        while(run_count > 0)
        {
            if(d->pid_tracker[index] == current->pid)
                return -EDEADLK;
            index--;
            if(index<0)
                index = MAX_MEM_SIZE - 1;
            run_count--;
        }
        //check loop deadlock
        
        
        
        if(filp_writable)
        {
            wait_event_interruptible(d->blockq, d->write_count == 0 && d->read_count == 0 && d->ticket_tail >= my_ticket);
            
            osp_spin_lock(&d->mutex);
            d->write_count++;
            d->ticket_tail++;
            filp->f_flags |= F_OSPRD_LOCKED;
            osp_spin_unlock(&d->mutex);
            
        }
        else
        {
            wait_event_interruptible(d->blockq, d->write_count == 0 && d->ticket_tail >= my_ticket);
            
            osp_spin_lock(&d->mutex);
            d->ticket_tail++;
            d->read_count++;
            filp->f_flags |= F_OSPRD_LOCKED;
            osp_spin_unlock(&d->mutex);
        }     

        r=0;
        
        
        /*
		eprintk("Attempting to acquire\n");
		r = -ENOTTY;
        */

	} else if (cmd == OSPRDIOCTRYACQUIRE) {

		// EXERCISE: ATTEMPT to lock the ramdisk.
		//
		// This is just like OSPRDIOCACQUIRE, except it should never
		// block.  If OSPRDIOCACQUIRE would block or return deadlock,
		// OSPRDIOCTRYACQUIRE should return -EBUSY.
		// Otherwise, if we can grant the lock request, return 0.

		// Your code here (instead of the next two lines).
        
#ifdef DEBUG
        eprintk("Handling TRY ACQUIRE\n");
#endif
        
        if(filp_writable)
        {
            osp_spin_lock(&d->mutex);
            if(write_condition(d))
            {
                d->write_count++;
                filp->f_flags |= F_OSPRD_LOCKED;
                osp_spin_unlock(&d->mutex);
            }
            else
            {
                osp_spin_unlock(&d->mutex);
                return -EBUSY;
            }
        }
        else
        {
            osp_spin_lock(&d->mutex);
            if(read_condition(d))
            {
                d->read_count++;
                filp->f_flags |= F_OSPRD_LOCKED;
                osp_spin_unlock(&d->mutex);
            }
            else
            {
                osp_spin_unlock(&d->mutex);
                return -EBUSY;
            }

        }
        r = 0;
        
        /*
		eprintk("Attempting to try acquire\n");
		r = -ENOTTY;
        */
	} else if (cmd == OSPRDIOCRELEASE) {
		// EXERCISE: Unlock the ramdisk.
		//
		// If the file hasn't locked the ramdisk, return -EINVAL.
		// Otherwise, clear the lock from filp->f_flags, wake up
		// the wait queue, perform any additional accounting steps
		// you need, and return 0.
        
		// Your code here (instead of the next line).

		//r = -ENOTTY;
        
        
#ifdef DEBUG
        eprintk("Handling RELEASE\n");
#endif
        
        if(filp->f_flags != F_OSPRD_LOCKED)
            return -EINVAL; //No lock on the ramdisk
        
        //check whether current process owns a lock
        osp_spin_lock(&d->mutex);
        int showup = 0;
        int run_count = d->read_count + d->write_count;
        int index = (d->ticket_tail - 1)%MAX_MEM_SIZE;
        osp_spin_unlock(&d->mutex);
        while(run_count > 0)
        {
            if(d->pid_tracker[index] == current->pid)
            {
                showup = 1;
                break;
            }
            index--;
            if(index<0)
                index = MAX_MEM_SIZE - 1;
            run_count--;
        }
        
        if(showup == 0)
            return -EINVAL;//current process don't own the lock
        
        
        osp_spin_lock(&d->mutex);
        filp->f_flags = 0;          //reset the flag?
        if(filp_writable)
        {
            d->write_count--;
        }
        else
        {
            d->read_count--;
        }
        wake_up_all(&d->blockq); //Wake up request that holds the next ticket
        osp_spin_unlock(&d->mutex);
        r = 0;
        
	} else
		r = -ENOTTY; /* unknown command */
	return r;
}