 723e51327f
			
		
	
	
		723e51327f
		
	
	
	
	
		
			
			The main purpose of this patch is to fix handling of unpause calls from PM while another call is ongoing. The solution to this problem sparked a full revision of the threading model, consisting of a large number of related changes: - all active worker threads are now always associated with a process, and every process has at most one active thread working for it; - the process lock is always held by a process's worker thread; - a process can now have both normal work and postponed PM work associated to it; - timer expiry and non-postponed PM work is done from the main thread; - filp garbage collection is done from a thread associated with VFS; - reboot calls from PM are now done from a thread associated with PM; - the DS events handler is protected from starting multiple threads; - support for a system worker thread has been removed; - the deadlock recovery thread has been replaced by a parameter to the worker_start() function; the number of worker threads has consequently been increased by one; - saving and restoring of global but per-thread variables is now centralized in worker_suspend() and worker_resume(); err_code is now saved and restored in all cases; - the concept of jobs has been removed, and job_m_in now points to a message stored in the worker thread structure instead; - the PM lock has been removed; - the separate exec lock has been replaced by a lock on the VM process, which was already being locked for exec calls anyway; - PM_UNPAUSE is now processed as a postponed PM request, from a thread associated with the target process; - the FP_DROP_WORK flag has been removed, since it is no longer more than just an optimization and only applied to processes operating on a pipe when getting killed; - assignment to "fp" now takes place only when obtaining new work in the main thread or a worker thread, when resuming execution of a thread, and in the special case of exiting processes during reboot; - there are no longer special cases where the yield() call is used to force a thread to run. Change-Id: I7a97b9b95c2450454a9b5318dfa0e6150d4e6858
		
			
				
	
	
		
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			67 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #include "fs.h"
 | |
| #include "file.h"
 | |
| 
 | |
| int gcov_flush(cp_grant_id_t grantid, size_t size );
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				do_gcov_flush				*
 | |
|  *===========================================================================*/
 | |
| int do_gcov_flush()
 | |
| {
 | |
| /* A userland tool has requested the gcov data from another
 | |
|  * process (possibly vfs itself). Grant the target process
 | |
|  * access to the supplied buffer, and perform the call that
 | |
|  * makes the target copy its buffer to the caller (incl vfs
 | |
|  * itself).
 | |
|  */
 | |
|   struct fproc *rfp;
 | |
|   ssize_t size;
 | |
|   cp_grant_id_t grantid;
 | |
|   int r, n;
 | |
|   pid_t target;
 | |
|   message m;
 | |
|   vir_bytes buf;
 | |
| 
 | |
|   size = job_m_in.GCOV_BUFF_SZ;
 | |
|   target = job_m_in.GCOV_PID;
 | |
|   buf = (vir_bytes) job_m_in.GCOV_BUFF_P;
 | |
| 
 | |
|   /* If the wrong process is sent to, the system hangs; so make this root-only.
 | |
|    */
 | |
| 
 | |
|   if (!super_user) return(EPERM);
 | |
| 
 | |
|   /* Find target gcov process. */
 | |
|   for(n = 0; n < NR_PROCS; n++) {
 | |
| 	if(fproc[n].fp_endpoint != NONE && fproc[n].fp_pid == target)
 | |
| 		 break;
 | |
|   }
 | |
|   if(n >= NR_PROCS) {
 | |
| 	printf("VFS: gcov process %d not found\n", target);
 | |
| 	return(ESRCH);
 | |
|   }
 | |
|   rfp = &fproc[n];
 | |
| 
 | |
|   /* Grant target process to requestor's buffer. */
 | |
|   if ((grantid = cpf_grant_magic(rfp->fp_endpoint, who_e, buf,
 | |
| 				 size, CPF_WRITE)) < 0) {
 | |
| 	printf("VFS: gcov_flush: grant failed\n");
 | |
| 	return(ENOMEM);
 | |
|   }
 | |
| 
 | |
|   if (rfp->fp_endpoint == VFS_PROC_NR) {
 | |
| 	/* Request is for VFS itself. */
 | |
| 	r = gcov_flush(grantid, size);
 | |
|   } else {
 | |
| 	/* Perform generic GCOV request. */
 | |
| 	m.GCOV_GRANT = grantid;
 | |
| 	m.GCOV_BUFF_SZ = size;
 | |
| 	r = _taskcall(rfp->fp_endpoint, COMMON_REQ_GCOV_DATA, &m);
 | |
|   }
 | |
| 
 | |
|   cpf_revoke(grantid);
 | |
| 
 | |
|   return(r);
 | |
| }
 |