xref: /minix3/minix/servers/pm/utility.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1  /* This file contains some utility routines for PM.
2   *
3   * The entry points are:
4   *   get_free_pid:	get a free process or group id
5   *   find_param:	look up a boot monitor parameter
6   *   find_proc:		return process pointer from pid number
7   *   nice_to_priority	convert nice level to priority queue
8   *   pm_isokendpt:	check the validity of an endpoint
9   *   tell_vfs:		send a request to VFS on behalf of a process
10   */
11  
12  #include "pm.h"
13  #include <sys/resource.h>
14  #include <sys/stat.h>
15  #include <minix/callnr.h>
16  #include <minix/com.h>
17  #include <minix/endpoint.h>
18  #include <fcntl.h>
19  #include <signal.h>		/* needed only because mproc.h needs it */
20  #include "mproc.h"
21  
22  #include <minix/config.h>
23  #include <minix/timers.h>
24  #include <machine/archtypes.h>
25  #include "kernel/const.h"
26  #include "kernel/config.h"
27  #include "kernel/type.h"
28  #include "kernel/proc.h"
29  
30  /*===========================================================================*
31   *				get_free_pid				     *
32   *===========================================================================*/
33  pid_t get_free_pid()
34  {
35    static pid_t next_pid = INIT_PID + 1;		/* next pid to be assigned */
36    register struct mproc *rmp;			/* check process table */
37    int t;					/* zero if pid still free */
38  
39    /* Find a free pid for the child and put it in the table. */
40    do {
41  	t = 0;
42  	next_pid = (next_pid < NR_PIDS ? next_pid + 1 : INIT_PID + 1);
43  	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
44  		if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
45  			t = 1;
46  			break;
47  		}
48    } while (t);					/* 't' = 0 means pid free */
49    return(next_pid);
50  }
51  
52  /*===========================================================================*
53   *				find_param				     *
54   *===========================================================================*/
55  char *find_param(name)
56  const char *name;
57  {
58    register const char *namep;
59    register char *envp;
60  
61    for (envp = (char *) monitor_params; *envp != 0;) {
62  	for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++)
63  		;
64  	if (*namep == '\0' && *envp == '=')
65  		return(envp + 1);
66  	while (*envp++ != 0)
67  		;
68    }
69    return(NULL);
70  }
71  
72  /*===========================================================================*
73   *				find_proc  				     *
74   *===========================================================================*/
75  struct mproc *find_proc(lpid)
76  pid_t lpid;
77  {
78    register struct mproc *rmp;
79  
80    for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
81  	if ((rmp->mp_flags & IN_USE) && rmp->mp_pid == lpid)
82  		return(rmp);
83  
84    return(NULL);
85  }
86  
87  /*===========================================================================*
88   *				nice_to_priority			     *
89   *===========================================================================*/
90  int nice_to_priority(int nice, unsigned* new_q)
91  {
92  	if (nice < PRIO_MIN || nice > PRIO_MAX) return(EINVAL);
93  
94  	*new_q = MAX_USER_Q + (nice-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) /
95  	    (PRIO_MAX-PRIO_MIN+1);
96  
97  	/* Neither of these should ever happen. */
98  	if ((signed) *new_q < MAX_USER_Q) *new_q = MAX_USER_Q;
99  	if (*new_q > MIN_USER_Q) *new_q = MIN_USER_Q;
100  
101  	return (OK);
102  }
103  
104  /*===========================================================================*
105   *				pm_isokendpt			 	     *
106   *===========================================================================*/
107  int pm_isokendpt(int endpoint, int *proc)
108  {
109  	*proc = _ENDPOINT_P(endpoint);
110  	if (*proc < 0 || *proc >= NR_PROCS)
111  		return EINVAL;
112  	if (endpoint != mproc[*proc].mp_endpoint)
113  		return EDEADEPT;
114  	if (!(mproc[*proc].mp_flags & IN_USE))
115  		return EDEADEPT;
116  	return OK;
117  }
118  
119  /*===========================================================================*
120   *				tell_vfs			 	     *
121   *===========================================================================*/
122  void tell_vfs(rmp, m_ptr)
123  struct mproc *rmp;
124  message *m_ptr;
125  {
126  /* Send a request to VFS, without blocking.
127   */
128    int r;
129  
130    if (rmp->mp_flags & VFS_CALL)
131  	panic("tell_vfs: not idle: %d", m_ptr->m_type);
132  
133    r = asynsend3(VFS_PROC_NR, m_ptr, AMF_NOREPLY);
134    if (r != OK)
135    	panic("unable to send to VFS: %d", r);
136  
137    rmp->mp_flags |= VFS_CALL;
138  }
139