host.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1993,1992,1991,1990,1989,1988 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. /*
  27. * host.c
  28. *
  29. * Non-ipc host functions.
  30. */
  31. #include <string.h>
  32. #include <kern/assert.h>
  33. #include <kern/debug.h>
  34. #include <kern/kalloc.h>
  35. #include <kern/host.h>
  36. #include <mach/host_info.h>
  37. #include <mach/kern_return.h>
  38. #include <mach/machine.h>
  39. #include <mach/port.h>
  40. #include <kern/processor.h>
  41. #include <kern/ipc_host.h>
  42. #include <kern/mach_clock.h>
  43. #include <mach/vm_param.h>
  44. host_data_t realhost;
  45. kern_return_t host_processors(
  46. const host_t host,
  47. processor_array_t *processor_list,
  48. natural_t *countp)
  49. {
  50. unsigned i;
  51. processor_t *tp;
  52. vm_offset_t addr;
  53. unsigned int count;
  54. if (host == HOST_NULL)
  55. return KERN_INVALID_ARGUMENT;
  56. /*
  57. * Determine how many processors we have.
  58. * (This number shouldn't change.)
  59. */
  60. count = 0;
  61. for (i = 0; i < NCPUS; i++)
  62. if (machine_slot[i].is_cpu)
  63. count++;
  64. if (count == 0)
  65. panic("host_processors");
  66. addr = kalloc((vm_size_t) (count * sizeof(mach_port_t)));
  67. if (addr == 0)
  68. return KERN_RESOURCE_SHORTAGE;
  69. tp = (processor_t *) addr;
  70. for (i = 0; i < NCPUS; i++)
  71. if (machine_slot[i].is_cpu)
  72. *tp++ = cpu_to_processor(i);
  73. *countp = count;
  74. *processor_list = (mach_port_t *) addr;
  75. /* do the conversion that Mig should handle */
  76. tp = (processor_t *) addr;
  77. for (i = 0; i < count; i++)
  78. ((mach_port_t *) tp)[i] =
  79. (mach_port_t)convert_processor_to_port(tp[i]);
  80. return KERN_SUCCESS;
  81. }
  82. kern_return_t host_info(
  83. const host_t host,
  84. int flavor,
  85. host_info_t info,
  86. natural_t *count)
  87. {
  88. integer_t i, *slot_ptr;
  89. if (host == HOST_NULL)
  90. return KERN_INVALID_ARGUMENT;
  91. switch(flavor) {
  92. case HOST_BASIC_INFO:
  93. {
  94. host_basic_info_t basic_info;
  95. /*
  96. * Basic information about this host.
  97. */
  98. if (*count < HOST_BASIC_INFO_COUNT)
  99. return KERN_FAILURE;
  100. basic_info = (host_basic_info_t) info;
  101. basic_info->max_cpus = machine_info.max_cpus;
  102. basic_info->avail_cpus = machine_info.avail_cpus;
  103. basic_info->memory_size = machine_info.memory_size;
  104. basic_info->cpu_type =
  105. machine_slot[master_processor->slot_num].cpu_type;
  106. basic_info->cpu_subtype =
  107. machine_slot[master_processor->slot_num].cpu_subtype;
  108. *count = HOST_BASIC_INFO_COUNT;
  109. return KERN_SUCCESS;
  110. }
  111. case HOST_PROCESSOR_SLOTS:
  112. /*
  113. * Return numbers of slots with active processors
  114. * in them.
  115. */
  116. if (*count < NCPUS)
  117. return KERN_INVALID_ARGUMENT;
  118. slot_ptr = (integer_t *)info;
  119. *count = 0;
  120. for (i = 0; i < NCPUS; i++) {
  121. if (machine_slot[i].is_cpu &&
  122. machine_slot[i].running) {
  123. *slot_ptr++ = i;
  124. (*count)++;
  125. }
  126. }
  127. return KERN_SUCCESS;
  128. case HOST_SCHED_INFO:
  129. {
  130. host_sched_info_t sched_info;
  131. extern int min_quantum;
  132. /* minimum quantum, in ticks */
  133. /*
  134. * Return scheduler information.
  135. */
  136. if (*count < HOST_SCHED_INFO_COUNT)
  137. return(KERN_FAILURE);
  138. sched_info = (host_sched_info_t) info;
  139. sched_info->min_timeout = tick / 1000;
  140. /* convert microseconds to milliseconds */
  141. sched_info->min_quantum = min_quantum * tick / 1000;
  142. /* convert ticks to milliseconds */
  143. *count = HOST_SCHED_INFO_COUNT;
  144. return KERN_SUCCESS;
  145. }
  146. case HOST_LOAD_INFO:
  147. {
  148. host_load_info_t load_info;
  149. extern long avenrun[3], mach_factor[3];
  150. if (*count < HOST_LOAD_INFO_COUNT)
  151. return KERN_FAILURE;
  152. load_info = (host_load_info_t) info;
  153. memcpy(load_info->avenrun,
  154. avenrun,
  155. sizeof avenrun);
  156. memcpy(load_info->mach_factor,
  157. mach_factor,
  158. sizeof mach_factor);
  159. *count = HOST_LOAD_INFO_COUNT;
  160. return KERN_SUCCESS;
  161. }
  162. default:
  163. return KERN_INVALID_ARGUMENT;
  164. }
  165. }
  166. /*
  167. * Return kernel version string (more than you ever
  168. * wanted to know about what version of the kernel this is).
  169. */
  170. kern_return_t host_kernel_version(
  171. const host_t host,
  172. kernel_version_t out_version)
  173. {
  174. extern char version[];
  175. if (host == HOST_NULL)
  176. return KERN_INVALID_ARGUMENT;
  177. (void) strncpy(out_version, version, sizeof(kernel_version_t));
  178. return KERN_SUCCESS;
  179. }
  180. /*
  181. * host_processor_sets:
  182. *
  183. * List all processor sets on the host.
  184. */
  185. #if MACH_HOST
  186. kern_return_t
  187. host_processor_sets(
  188. const host_t host,
  189. processor_set_name_array_t *pset_list,
  190. natural_t *count)
  191. {
  192. unsigned int actual; /* this many psets */
  193. processor_set_t pset;
  194. processor_set_t *psets;
  195. int i;
  196. vm_size_t size;
  197. vm_size_t size_needed;
  198. vm_offset_t addr;
  199. if (host == HOST_NULL)
  200. return KERN_INVALID_ARGUMENT;
  201. size = 0; addr = 0;
  202. for (;;) {
  203. simple_lock(&all_psets_lock);
  204. actual = all_psets_count;
  205. /* do we have the memory we need? */
  206. size_needed = actual * sizeof(mach_port_t);
  207. if (size_needed <= size)
  208. break;
  209. /* unlock and allocate more memory */
  210. simple_unlock(&all_psets_lock);
  211. if (size != 0)
  212. kfree(addr, size);
  213. assert(size_needed > 0);
  214. size = size_needed;
  215. addr = kalloc(size);
  216. if (addr == 0)
  217. return KERN_RESOURCE_SHORTAGE;
  218. }
  219. /* OK, have memory and the all_psets_lock */
  220. psets = (processor_set_t *) addr;
  221. for (i = 0, pset = (processor_set_t) queue_first(&all_psets);
  222. i < actual;
  223. i++, pset = (processor_set_t) queue_next(&pset->all_psets)) {
  224. /* take ref for convert_pset_name_to_port */
  225. pset_reference(pset);
  226. psets[i] = pset;
  227. }
  228. assert(queue_end(&all_psets, (queue_entry_t) pset));
  229. /* can unlock now that we've got the pset refs */
  230. simple_unlock(&all_psets_lock);
  231. /*
  232. * Always have default port.
  233. */
  234. assert(actual > 0);
  235. /* if we allocated too much, must copy */
  236. if (size_needed < size) {
  237. vm_offset_t newaddr;
  238. newaddr = kalloc(size_needed);
  239. if (newaddr == 0) {
  240. for (i = 0; i < actual; i++)
  241. pset_deallocate(psets[i]);
  242. kfree(addr, size);
  243. return KERN_RESOURCE_SHORTAGE;
  244. }
  245. memcpy((void *) newaddr, (void *) addr, size_needed);
  246. kfree(addr, size);
  247. psets = (processor_set_t *) newaddr;
  248. }
  249. *pset_list = (mach_port_t *) psets;
  250. *count = actual;
  251. /* do the conversion that Mig should handle */
  252. for (i = 0; i < actual; i++)
  253. ((mach_port_t *) psets)[i] =
  254. (mach_port_t)convert_pset_name_to_port(psets[i]);
  255. return KERN_SUCCESS;
  256. }
  257. #else /* MACH_HOST */
  258. /*
  259. * Only one processor set, the default processor set, in this case.
  260. */
  261. kern_return_t
  262. host_processor_sets(
  263. const host_t host,
  264. processor_set_name_array_t *pset_list,
  265. natural_t *count)
  266. {
  267. vm_offset_t addr;
  268. if (host == HOST_NULL)
  269. return KERN_INVALID_ARGUMENT;
  270. /*
  271. * Allocate memory. Can be pageable because it won't be
  272. * touched while holding a lock.
  273. */
  274. addr = kalloc((vm_size_t) sizeof(mach_port_t));
  275. if (addr == 0)
  276. return KERN_RESOURCE_SHORTAGE;
  277. /* take for for convert_pset_name_to_port */
  278. pset_reference(&default_pset);
  279. /* do the conversion that Mig should handle */
  280. *((mach_port_t *) addr) =
  281. (mach_port_t) convert_pset_name_to_port(&default_pset);
  282. *pset_list = (mach_port_t *) addr;
  283. *count = 1;
  284. return KERN_SUCCESS;
  285. }
  286. #endif /* MACH_HOST */
  287. /*
  288. * host_processor_set_priv:
  289. *
  290. * Return control port for given processor set.
  291. */
  292. kern_return_t
  293. host_processor_set_priv(
  294. const host_t host,
  295. processor_set_t pset_name,
  296. processor_set_t *pset)
  297. {
  298. if ((host == HOST_NULL) || (pset_name == PROCESSOR_SET_NULL)) {
  299. *pset = PROCESSOR_SET_NULL;
  300. return KERN_INVALID_ARGUMENT;
  301. }
  302. *pset = pset_name;
  303. pset_reference(*pset);
  304. return KERN_SUCCESS;
  305. }