1 /* This file contains some utility routines for RS.
4 * Nov 22, 2009: Created (Cristiano Giuffrida)
10 #include <minix/sched.h>
11 #include "kernel/proc.h"
13 /*===========================================================================*
15 *===========================================================================*/
16 int init_service(rp
, type
)
17 struct rproc
*rp
; /* pointer to process slot */
18 int type
; /* type of initialization */
22 struct rprocpub
*rpub
;
23 endpoint_t old_endpoint
;
27 rp
->r_flags
|= RS_INITIALIZING
; /* now initializing */
28 rp
->r_check_tm
= rp
->r_alive_tm
+ 1; /* expect reply within period */
30 /* In case of RS initialization, we are done. */
31 if(rp
->r_priv
.s_flags
& ROOT_SYS_PROC
) {
35 /* Determine the old endpoint if this is a new instance. */
38 old_endpoint
= rp
->r_old_rp
->r_pub
->endpoint
;
40 else if(rp
->r_prev_rp
) {
41 old_endpoint
= rp
->r_prev_rp
->r_pub
->endpoint
;
44 /* Send initialization message. */
46 m
.RS_INIT_TYPE
= type
;
47 m
.RS_INIT_RPROCTAB_GID
= rinit
.rproctab_gid
;
48 m
.RS_INIT_OLD_ENDPOINT
= old_endpoint
;
49 r
= asynsend(rpub
->endpoint
, &m
);
54 /*===========================================================================*
56 *===========================================================================*/
57 void fill_send_mask(send_mask
, set_bits
)
58 sys_map_t
*send_mask
; /* the send mask to fill in */
59 int set_bits
; /* TRUE sets all bits, FALSE clears all bits */
61 /* Fill in a send mask. */
64 for (i
= 0; i
< NR_SYS_PROCS
; i
++) {
66 set_sys_bit(*send_mask
, i
);
68 unset_sys_bit(*send_mask
, i
);
72 /*===========================================================================*
74 *===========================================================================*/
75 void fill_call_mask(calls
, tot_nr_calls
, call_mask
, call_base
, is_init
)
76 int *calls
; /* the unordered set of calls */
77 int tot_nr_calls
; /* the total number of calls */
78 bitchunk_t
*call_mask
; /* the call mask to fill in */
79 int call_base
; /* the base offset for the calls */
80 int is_init
; /* set when initializing a call mask */
82 /* Fill a call mask from an unordered set of calls. */
84 int call_mask_size
, nr_calls
;
86 call_mask_size
= BITMAP_CHUNKS(tot_nr_calls
);
88 /* Count the number of calls to fill in. */
90 for(i
=0; calls
[i
] != NULL_C
; i
++) {
94 /* See if all calls are allowed and call mask must be completely filled. */
95 if(nr_calls
== 1 && calls
[0] == ALL_C
) {
96 for(i
=0; i
< call_mask_size
; i
++) {
101 /* When initializing, reset the mask first. */
103 for(i
=0; i
< call_mask_size
; i
++) {
107 /* Enter calls bit by bit. */
108 for(i
=0; i
< nr_calls
; i
++) {
109 SET_BIT(call_mask
, calls
[i
] - call_base
);
114 /*===========================================================================*
116 *===========================================================================*/
117 char* srv_to_string(rp
)
118 struct rproc
*rp
; /* pointer to process slot */
120 struct rprocpub
*rpub
;
123 static char srv_string_pool
[3][RS_MAX_LABEL_LEN
+ (DEBUG
? 256 : 64)];
124 static int srv_string_pool_index
= 0;
127 slot_nr
= rp
- rproc
;
128 srv_string
= srv_string_pool
[srv_string_pool_index
];
129 srv_string_pool_index
= (srv_string_pool_index
+ 1) % 3;
131 #define srv_str(cmd) ((cmd) == NULL || (cmd)[0] == '\0' ? "_" : (cmd))
132 #define srv_ep_str(rp) (itoa((rp)->r_pub->endpoint))
133 #define srv_active_str(rp) ((rp)->r_flags & RS_ACTIVE ? "*" : " ")
134 #define srv_version_str(rp) ((rp)->r_new_rp || (rp)->r_next_rp ? "-" : \
135 ((rp)->r_old_rp || (rp)->r_prev_rp ? "+" : " "))
138 sprintf(srv_string
, "service '%s'%s%s(slot %d, ep %d, pid %d, cmd %s, script %s, proc %s, major %d, style %d, flags 0x%03x, sys_flags 0x%02x)",
139 rpub
->label
, srv_active_str(rp
), srv_version_str(rp
),
140 slot_nr
, rpub
->endpoint
, rp
->r_pid
, srv_str(rp
->r_cmd
),
141 srv_str(rp
->r_script
), srv_str(rpub
->proc_name
), rpub
->dev_nr
,
142 rpub
->dev_style
, rp
->r_flags
, rpub
->sys_flags
);
144 sprintf(srv_string
, "service '%s'%s%s(slot %d, ep %d, pid %d)",
145 rpub
->label
, srv_active_str(rp
), srv_version_str(rp
),
146 slot_nr
, rpub
->endpoint
, rp
->r_pid
);
152 /*===========================================================================*
154 *===========================================================================*/
155 void reply(who
, rp
, m_ptr
)
156 endpoint_t who
; /* replyee */
157 struct rproc
*rp
; /* replyee slot (if any) */
158 message
*m_ptr
; /* reply message */
160 int r
; /* send status */
162 /* No need to actually reply to RS */
163 if(who
== RS_PROC_NR
) {
168 printf("RS: %s being replied to\n", srv_to_string(rp
));
170 r
= sendnb(who
, m_ptr
); /* send the message */
172 printf("RS: unable to send reply to %d: %d\n", who
, r
);
175 /*===========================================================================*
177 *===========================================================================*/
178 void late_reply(rp
, code
)
179 struct rproc
*rp
; /* pointer to process slot */
180 int code
; /* status code */
182 /* If a caller is waiting for a reply, unblock it. */
183 if(rp
->r_flags
& RS_LATEREPLY
) {
187 printf("RS: %s late reply %d to %d for request %d\n",
188 srv_to_string(rp
), code
, rp
->r_caller
, rp
->r_caller_request
);
190 reply(rp
->r_caller
, NULL
, &m
);
191 rp
->r_flags
&= ~RS_LATEREPLY
;
195 /*===========================================================================*
197 *===========================================================================*/
198 int rs_isokendpt(endpoint_t endpoint
, int *proc
)
200 *proc
= _ENDPOINT_P(endpoint
);
201 if(*proc
< -NR_TASKS
|| *proc
>= NR_PROCS
)
207 /*===========================================================================*
209 *===========================================================================*/
210 int sched_init_proc(struct rproc
*rp
)
215 /* Make sure user processes have no scheduler. PM deals with them. */
216 is_usr_proc
= !(rp
->r_priv
.s_flags
& SYS_PROC
);
217 if(is_usr_proc
) assert(rp
->r_scheduler
== NONE
);
218 if(!is_usr_proc
) assert(rp
->r_scheduler
!= NONE
);
220 /* Start scheduling for the given process. */
221 if ((s
= sched_start(rp
->r_scheduler
, rp
->r_pub
->endpoint
,
222 RS_PROC_NR
, rp
->r_priority
, rp
->r_quantum
, rp
->r_cpu
,
223 &rp
->r_scheduler
)) != OK
) {
230 /*===========================================================================*
232 *===========================================================================*/
233 int update_sig_mgrs(struct rproc
*rp
, endpoint_t sig_mgr
,
234 endpoint_t bak_sig_mgr
)
237 struct rprocpub
*rpub
;
242 printf("RS: %s updates signal managers: %d%s / %d\n", srv_to_string(rp
),
243 sig_mgr
== SELF
? rpub
->endpoint
: sig_mgr
,
244 sig_mgr
== SELF
? "(SELF)" : "",
245 bak_sig_mgr
== NONE
? -1 : bak_sig_mgr
);
247 /* Synch privilege structure with the kernel. */
248 if ((r
= sys_getpriv(&rp
->r_priv
, rpub
->endpoint
)) != OK
) {
249 printf("unable to synch privilege structure: %d", r
);
253 /* Set signal managers. */
254 rp
->r_priv
.s_sig_mgr
= sig_mgr
;
255 rp
->r_priv
.s_bak_sig_mgr
= bak_sig_mgr
;
257 /* Update privilege structure. */
258 r
= sys_privctl(rpub
->endpoint
, SYS_PRIV_UPDATE_SYS
, &rp
->r_priv
);
260 printf("unable to update privilege structure: %d", r
);