xref: /haiku/src/apps/activitymonitor/DataSource.cpp (revision 746cac055adc6ac3308c7bc2d29040fb95689cc9)
1 /*
2  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "DataSource.h"
8 
9 #include <stdio.h>
10 #include <stdint.h>
11 
12 #include <OS.h>
13 #include <String.h>
14 
15 #include "SystemInfo.h"
16 
17 
18 const DataSource* kSources[] = {
19 	new UsedMemoryDataSource(),
20 	new CachedMemoryDataSource(),
21 	new SemaphoresDataSource(),
22 	new PortsDataSource(),
23 	new ThreadsDataSource(),
24 	new TeamsDataSource(),
25 	new RunningAppsDataSource(),
26 	new CPUUsageDataSource(),
27 	new CPUCombinedUsageDataSource(),
28 	new NetworkUsageDataSource(true),
29 	new NetworkUsageDataSource(false),
30 	new ClipboardSizeDataSource(false),
31 	new ClipboardSizeDataSource(true),
32 	new MediaNodesDataSource()
33 };
34 const size_t kSourcesCount = sizeof(kSources) / sizeof(kSources[0]);
35 
36 
37 DataSource::DataSource(int64 initialMin, int64 initialMax)
38 	:
39 	fMinimum(initialMin),
40 	fMaximum(initialMax),
41 	fInterval(1000000LL),
42 	fColor((rgb_color){200, 0, 0})
43 {
44 }
45 
46 
47 DataSource::DataSource()
48 	:
49 	fMinimum(0),
50 	fMaximum(100),
51 	fInterval(1000000LL),
52 	fColor((rgb_color){200, 0, 0})
53 {
54 }
55 
56 
57 DataSource::DataSource(const DataSource& other)
58 {
59 	fMinimum = other.fMinimum;
60 	fMaximum = other.fMaximum;
61 	fInterval = other.fInterval;
62 	fColor = other.fColor;
63 }
64 
65 
66 DataSource::~DataSource()
67 {
68 }
69 
70 
71 DataSource*
72 DataSource::Copy() const
73 {
74 	return NULL;
75 		// this class cannot be copied
76 }
77 
78 
79 DataSource*
80 DataSource::CopyForCPU(int32 cpu) const
81 {
82 	return Copy();
83 }
84 
85 
86 int64
87 DataSource::Minimum() const
88 {
89 	return fMinimum;
90 }
91 
92 
93 int64
94 DataSource::Maximum() const
95 {
96 	return fMaximum;
97 }
98 
99 
100 bigtime_t
101 DataSource::RefreshInterval() const
102 {
103 	return fInterval;
104 }
105 
106 
107 void
108 DataSource::SetLimits(int64 min, int64 max)
109 {
110 	fMinimum = min;
111 	fMaximum = max;
112 }
113 
114 
115 void
116 DataSource::SetRefreshInterval(bigtime_t interval)
117 {
118 	fInterval = interval;
119 }
120 
121 
122 void
123 DataSource::SetColor(rgb_color color)
124 {
125 	fColor = color;
126 }
127 
128 
129 int64
130 DataSource::NextValue(SystemInfo& info)
131 {
132 	return 0;
133 }
134 
135 
136 void
137 DataSource::Print(BString& text, int64 value) const
138 {
139 	text = "";
140 	text << value;
141 }
142 
143 
144 const char*
145 DataSource::Name() const
146 {
147 	return Label();
148 }
149 
150 
151 const char*
152 DataSource::Label() const
153 {
154 	return "";
155 }
156 
157 
158 const char*
159 DataSource::Unit() const
160 {
161 	return "";
162 }
163 
164 
165 rgb_color
166 DataSource::Color() const
167 {
168 	return fColor;
169 }
170 
171 
172 bool
173 DataSource::AdaptiveScale() const
174 {
175 	return false;
176 }
177 
178 
179 scale_type
180 DataSource::ScaleType() const
181 {
182 	return kNoScale;
183 }
184 
185 
186 int32
187 DataSource::CPU() const
188 {
189 	return 0;
190 }
191 
192 
193 bool
194 DataSource::PerCPU() const
195 {
196 	return false;
197 }
198 
199 
200 bool
201 DataSource::MultiCPUOnly() const
202 {
203 	return false;
204 }
205 
206 
207 bool
208 DataSource::Primary() const
209 {
210 	return false;
211 }
212 
213 
214 /*static*/ int32
215 DataSource::CountSources()
216 {
217 	return kSourcesCount;
218 }
219 
220 
221 /*static*/ const DataSource*
222 DataSource::SourceAt(int32 index)
223 {
224 	if (index >= (int32)kSourcesCount || index < 0)
225 		return NULL;
226 
227 	return kSources[index];
228 }
229 
230 
231 /*static*/ const DataSource*
232 DataSource::FindSource(const char* name)
233 {
234 	for (uint32 i = 0; i < kSourcesCount; i++) {
235 		const DataSource* source = kSources[i];
236 		if (!strcmp(source->Name(), name))
237 			return source;
238 	}
239 
240 	return NULL;
241 }
242 
243 
244 /*static*/ int32
245 DataSource::IndexOf(const DataSource* source)
246 {
247 	const char* name = source->Name();
248 
249 	for (uint32 i = 0; i < kSourcesCount; i++) {
250 		if (!strcmp(kSources[i]->Name(), name))
251 			return i;
252 	}
253 
254 	return -1;
255 }
256 
257 
258 //	#pragma mark -
259 
260 
261 MemoryDataSource::MemoryDataSource()
262 {
263 	SystemInfo info;
264 
265 	fMinimum = 0;
266 	fMaximum = info.MaxMemory();
267 }
268 
269 
270 MemoryDataSource::~MemoryDataSource()
271 {
272 }
273 
274 
275 void
276 MemoryDataSource::Print(BString& text, int64 value) const
277 {
278 	char buffer[32];
279 	snprintf(buffer, sizeof(buffer), "%.1f MB", value / 1048576.0);
280 
281 	text = buffer;
282 }
283 
284 
285 const char*
286 MemoryDataSource::Unit() const
287 {
288 	return "MB";
289 }
290 
291 
292 //	#pragma mark -
293 
294 
295 UsedMemoryDataSource::UsedMemoryDataSource()
296 {
297 }
298 
299 
300 UsedMemoryDataSource::~UsedMemoryDataSource()
301 {
302 }
303 
304 
305 DataSource*
306 UsedMemoryDataSource::Copy() const
307 {
308 	return new UsedMemoryDataSource(*this);
309 }
310 
311 
312 int64
313 UsedMemoryDataSource::NextValue(SystemInfo& info)
314 {
315 	return info.UsedMemory();
316 }
317 
318 
319 const char*
320 UsedMemoryDataSource::Label() const
321 {
322 	return "Used Memory";
323 }
324 
325 
326 bool
327 UsedMemoryDataSource::Primary() const
328 {
329 	return true;
330 }
331 
332 
333 //	#pragma mark -
334 
335 
336 CachedMemoryDataSource::CachedMemoryDataSource()
337 {
338 	fColor = (rgb_color){0, 200, 0};
339 }
340 
341 
342 CachedMemoryDataSource::~CachedMemoryDataSource()
343 {
344 }
345 
346 
347 DataSource*
348 CachedMemoryDataSource::Copy() const
349 {
350 	return new CachedMemoryDataSource(*this);
351 }
352 
353 
354 int64
355 CachedMemoryDataSource::NextValue(SystemInfo& info)
356 {
357 	return info.CachedMemory();
358 }
359 
360 
361 const char*
362 CachedMemoryDataSource::Label() const
363 {
364 	return "Cached Memory";
365 }
366 
367 
368 bool
369 CachedMemoryDataSource::Primary() const
370 {
371 	return true;
372 }
373 
374 
375 //	#pragma mark -
376 
377 
378 SemaphoresDataSource::SemaphoresDataSource()
379 {
380 	SystemInfo info;
381 
382 	fMinimum = 0;
383 	fMaximum = info.MaxSemaphores();
384 
385 	fColor = (rgb_color){100, 200, 100};
386 }
387 
388 
389 SemaphoresDataSource::~SemaphoresDataSource()
390 {
391 }
392 
393 
394 DataSource*
395 SemaphoresDataSource::Copy() const
396 {
397 	return new SemaphoresDataSource(*this);
398 }
399 
400 
401 int64
402 SemaphoresDataSource::NextValue(SystemInfo& info)
403 {
404 	return info.UsedSemaphores();
405 }
406 
407 
408 const char*
409 SemaphoresDataSource::Label() const
410 {
411 	return "Semaphores";
412 }
413 
414 
415 bool
416 SemaphoresDataSource::AdaptiveScale() const
417 {
418 	return true;
419 }
420 
421 
422 //	#pragma mark -
423 
424 
425 PortsDataSource::PortsDataSource()
426 {
427 	SystemInfo info;
428 
429 	fMinimum = 0;
430 	fMaximum = info.MaxPorts();
431 
432 	fColor = (rgb_color){180, 200, 180};
433 }
434 
435 
436 PortsDataSource::~PortsDataSource()
437 {
438 }
439 
440 
441 DataSource*
442 PortsDataSource::Copy() const
443 {
444 	return new PortsDataSource(*this);
445 }
446 
447 
448 int64
449 PortsDataSource::NextValue(SystemInfo& info)
450 {
451 	return info.UsedPorts();
452 }
453 
454 
455 const char*
456 PortsDataSource::Label() const
457 {
458 	return "Ports";
459 }
460 
461 
462 bool
463 PortsDataSource::AdaptiveScale() const
464 {
465 	return true;
466 }
467 
468 
469 //	#pragma mark -
470 
471 
472 ThreadsDataSource::ThreadsDataSource()
473 {
474 	SystemInfo info;
475 
476 	fMinimum = 0;
477 	fMaximum = info.MaxThreads();
478 
479 	fColor = (rgb_color){0, 0, 200};
480 }
481 
482 
483 ThreadsDataSource::~ThreadsDataSource()
484 {
485 }
486 
487 
488 DataSource*
489 ThreadsDataSource::Copy() const
490 {
491 	return new ThreadsDataSource(*this);
492 }
493 
494 
495 int64
496 ThreadsDataSource::NextValue(SystemInfo& info)
497 {
498 	return info.UsedThreads();
499 }
500 
501 
502 const char*
503 ThreadsDataSource::Label() const
504 {
505 	return "Threads";
506 }
507 
508 
509 bool
510 ThreadsDataSource::AdaptiveScale() const
511 {
512 	return true;
513 }
514 
515 
516 //	#pragma mark -
517 
518 
519 TeamsDataSource::TeamsDataSource()
520 {
521 	SystemInfo info;
522 
523 	fMinimum = 0;
524 	fMaximum = info.MaxTeams();
525 
526 	fColor = (rgb_color){0, 150, 255};
527 }
528 
529 
530 TeamsDataSource::~TeamsDataSource()
531 {
532 }
533 
534 
535 DataSource*
536 TeamsDataSource::Copy() const
537 {
538 	return new TeamsDataSource(*this);
539 }
540 
541 
542 int64
543 TeamsDataSource::NextValue(SystemInfo& info)
544 {
545 	return info.UsedTeams();
546 }
547 
548 
549 const char*
550 TeamsDataSource::Label() const
551 {
552 	return "Teams";
553 }
554 
555 
556 bool
557 TeamsDataSource::AdaptiveScale() const
558 {
559 	return true;
560 }
561 
562 
563 //	#pragma mark -
564 
565 
566 RunningAppsDataSource::RunningAppsDataSource()
567 {
568 	SystemInfo info;
569 
570 	fMinimum = 0;
571 	fMaximum = info.MaxRunningApps();
572 
573 	fColor = (rgb_color){100, 150, 255};
574 }
575 
576 
577 RunningAppsDataSource::~RunningAppsDataSource()
578 {
579 }
580 
581 
582 DataSource*
583 RunningAppsDataSource::Copy() const
584 {
585 	return new RunningAppsDataSource(*this);
586 }
587 
588 
589 int64
590 RunningAppsDataSource::NextValue(SystemInfo& info)
591 {
592 	return info.UsedRunningApps();
593 }
594 
595 
596 const char*
597 RunningAppsDataSource::Label() const
598 {
599 	return "Running Applications";
600 }
601 
602 
603 bool
604 RunningAppsDataSource::AdaptiveScale() const
605 {
606 	return true;
607 }
608 
609 
610 //	#pragma mark -
611 
612 
613 CPUUsageDataSource::CPUUsageDataSource(int32 cpu)
614 	:
615 	fPreviousActive(0),
616 	fPreviousTime(0)
617 {
618 	fMinimum = 0;
619 	fMaximum = 1000;
620 
621 	_SetCPU(cpu);
622 }
623 
624 
625 CPUUsageDataSource::CPUUsageDataSource(const CPUUsageDataSource& other)
626 	: DataSource(other)
627 {
628 	fPreviousActive = other.fPreviousActive;
629 	fPreviousTime = other.fPreviousTime;
630 	fCPU = other.fCPU;
631 	fLabel = other.fLabel;
632 }
633 
634 
635 CPUUsageDataSource::~CPUUsageDataSource()
636 {
637 }
638 
639 
640 DataSource*
641 CPUUsageDataSource::Copy() const
642 {
643 	return new CPUUsageDataSource(*this);
644 }
645 
646 
647 DataSource*
648 CPUUsageDataSource::CopyForCPU(int32 cpu) const
649 {
650 	CPUUsageDataSource* copy = new CPUUsageDataSource(*this);
651 	copy->_SetCPU(cpu);
652 
653 	return copy;
654 }
655 
656 
657 void
658 CPUUsageDataSource::Print(BString& text, int64 value) const
659 {
660 	char buffer[32];
661 	snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
662 
663 	text = buffer;
664 }
665 
666 
667 int64
668 CPUUsageDataSource::NextValue(SystemInfo& info)
669 {
670 	bigtime_t active = info.Info().cpu_infos[fCPU].active_time;
671 
672 	int64 percent = int64(1000.0 * (active - fPreviousActive)
673 		/ (info.Time() - fPreviousTime));
674 	if (percent < 0)
675 		percent = 0;
676 	if (percent > 1000)
677 		percent = 1000;
678 
679 	fPreviousActive = active;
680 	fPreviousTime = info.Time();
681 
682 	return percent;
683 }
684 
685 
686 const char*
687 CPUUsageDataSource::Label() const
688 {
689 	return fLabel.String();
690 }
691 
692 
693 const char*
694 CPUUsageDataSource::Name() const
695 {
696 	return "CPU Usage";
697 }
698 
699 
700 int32
701 CPUUsageDataSource::CPU() const
702 {
703 	return fCPU;
704 }
705 
706 
707 bool
708 CPUUsageDataSource::PerCPU() const
709 {
710 	return true;
711 }
712 
713 
714 bool
715 CPUUsageDataSource::Primary() const
716 {
717 	return true;
718 }
719 
720 
721 void
722 CPUUsageDataSource::_SetCPU(int32 cpu)
723 {
724 	fCPU = cpu;
725 	fLabel = "CPU";
726 	if (SystemInfo().CPUCount() > 1)
727 		fLabel << " " << cpu;
728 
729 	fLabel << " Usage";
730 
731 	const rgb_color kColors[] = {
732 		// TODO: find some better defaults...
733 		{200, 0, 200},
734 		{0, 200, 200},
735 		{80, 80, 80},
736 		{230, 150, 50},
737 	};
738 	const uint32 kNumColors = sizeof(kColors) / sizeof(kColors[0]);
739 
740 	fColor = kColors[cpu % kNumColors];
741 }
742 
743 
744 //	#pragma mark -
745 
746 
747 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource()
748 	:
749 	fPreviousActive(0),
750 	fPreviousTime(0)
751 {
752 	fMinimum = 0;
753 	fMaximum = 1000;
754 
755 	fColor = (rgb_color){200, 200, 0};
756 }
757 
758 
759 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource(
760 		const CPUCombinedUsageDataSource& other)
761 	: DataSource(other)
762 {
763 	fPreviousActive = other.fPreviousActive;
764 	fPreviousTime = other.fPreviousTime;
765 }
766 
767 
768 CPUCombinedUsageDataSource::~CPUCombinedUsageDataSource()
769 {
770 }
771 
772 
773 DataSource*
774 CPUCombinedUsageDataSource::Copy() const
775 {
776 	return new CPUCombinedUsageDataSource(*this);
777 }
778 
779 
780 void
781 CPUCombinedUsageDataSource::Print(BString& text, int64 value) const
782 {
783 	char buffer[32];
784 	snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
785 
786 	text = buffer;
787 }
788 
789 
790 int64
791 CPUCombinedUsageDataSource::NextValue(SystemInfo& info)
792 {
793 	int32 running = 0;
794 	bigtime_t active = 0;
795 
796 	for (int32 cpu = 0; cpu < info.Info().cpu_count; cpu++) {
797 		active += info.Info().cpu_infos[cpu].active_time;
798 		running++;
799 			// TODO: take disabled CPUs into account
800 	}
801 
802 	int64 percent = int64(1000.0 * (active - fPreviousActive)
803 		/ (running * (info.Time() - fPreviousTime)));
804 	if (percent < 0)
805 		percent = 0;
806 	if (percent > 1000)
807 		percent = 1000;
808 
809 	fPreviousActive = active;
810 	fPreviousTime = info.Time();
811 
812 	return percent;
813 }
814 
815 
816 const char*
817 CPUCombinedUsageDataSource::Label() const
818 {
819 	return "CPU Usage";
820 }
821 
822 
823 const char*
824 CPUCombinedUsageDataSource::Name() const
825 {
826 	return "CPU Usage (combined)";
827 }
828 
829 
830 bool
831 CPUCombinedUsageDataSource::MultiCPUOnly() const
832 {
833 	return true;
834 }
835 
836 
837 bool
838 CPUCombinedUsageDataSource::Primary() const
839 {
840 	return true;
841 }
842 
843 
844 //	#pragma mark -
845 
846 
847 NetworkUsageDataSource::NetworkUsageDataSource(bool in)
848 	:
849 	fIn(in),
850 	fPreviousBytes(0),
851 	fPreviousTime(0)
852 {
853 	SystemInfo info;
854 	NextValue(info);
855 
856 	fMinimum = 0;
857 	fMaximum = 1000000000LL;
858 
859 	fColor = fIn ? (rgb_color){200, 150, 0} : (rgb_color){200, 220, 0};
860 }
861 
862 
863 NetworkUsageDataSource::NetworkUsageDataSource(
864 		const NetworkUsageDataSource& other)
865 	: DataSource(other)
866 {
867 	fIn = other.fIn;
868 	fPreviousBytes = other.fPreviousBytes;
869 	fPreviousTime = other.fPreviousTime;
870 }
871 
872 
873 NetworkUsageDataSource::~NetworkUsageDataSource()
874 {
875 }
876 
877 
878 DataSource*
879 NetworkUsageDataSource::Copy() const
880 {
881 	return new NetworkUsageDataSource(*this);
882 }
883 
884 
885 void
886 NetworkUsageDataSource::Print(BString& text, int64 value) const
887 {
888 	char buffer[32];
889 	snprintf(buffer, sizeof(buffer), "%.1f KB/s", value / 1024.0);
890 
891 	text = buffer;
892 }
893 
894 
895 int64
896 NetworkUsageDataSource::NextValue(SystemInfo& info)
897 {
898 	uint64 transferred = fIn ? info.NetworkReceived() : info.NetworkSent();
899 
900 	int64 bytesPerSecond = uint64(double(transferred - fPreviousBytes)
901 		/ (info.Time() - fPreviousTime) * 1000000.0);
902 
903 	fPreviousBytes = transferred;
904 	fPreviousTime = info.Time();
905 
906 	return bytesPerSecond;
907 }
908 
909 
910 const char*
911 NetworkUsageDataSource::Label() const
912 {
913 	return fIn ? "Receiving" : "Sending";
914 }
915 
916 
917 const char*
918 NetworkUsageDataSource::Name() const
919 {
920 	return fIn ? "Network Receive" : "Network Send";
921 }
922 
923 
924 bool
925 NetworkUsageDataSource::AdaptiveScale() const
926 {
927 	return true;
928 }
929 
930 
931 bool
932 NetworkUsageDataSource::Primary() const
933 {
934 	return true;
935 }
936 
937 
938 //	#pragma mark -
939 
940 
941 ClipboardSizeDataSource::ClipboardSizeDataSource(bool text)
942 {
943 	fMinimum = 0;
944 	fMaximum = UINT32_MAX;
945 	fText = text;
946 
947 	fColor = (rgb_color){0, 150, 255};
948 }
949 
950 
951 ClipboardSizeDataSource::ClipboardSizeDataSource(
952 		const ClipboardSizeDataSource& other)
953 	: DataSource(other)
954 {
955 	fText = other.fText;
956 }
957 
958 
959 ClipboardSizeDataSource::~ClipboardSizeDataSource()
960 {
961 }
962 
963 
964 DataSource*
965 ClipboardSizeDataSource::Copy() const
966 {
967 	return new ClipboardSizeDataSource(*this);
968 }
969 
970 
971 int64
972 ClipboardSizeDataSource::NextValue(SystemInfo& info)
973 {
974 	if (fText)
975 		return info.ClipboardTextSize()/* / 1024*/;
976 	return info.ClipboardSize()/* / 1024*/;
977 }
978 
979 
980 const char*
981 ClipboardSizeDataSource::Label() const
982 {
983 	return fText ? "Text Clipboard Size" : "Raw Clipboard Size";
984 }
985 
986 
987 const char*
988 ClipboardSizeDataSource::Unit() const
989 {
990 	return "bytes"/*"KB"*/;
991 }
992 
993 
994 bool
995 ClipboardSizeDataSource::AdaptiveScale() const
996 {
997 	return true;
998 }
999 
1000 
1001 //	#pragma mark -
1002 
1003 
1004 MediaNodesDataSource::MediaNodesDataSource()
1005 {
1006 	SystemInfo info;
1007 
1008 	fMinimum = 0;
1009 	fMaximum = INT32_MAX;
1010 
1011 	fColor = (rgb_color){255, 150, 225};
1012 }
1013 
1014 
1015 MediaNodesDataSource::~MediaNodesDataSource()
1016 {
1017 }
1018 
1019 
1020 DataSource*
1021 MediaNodesDataSource::Copy() const
1022 {
1023 	return new MediaNodesDataSource(*this);
1024 }
1025 
1026 
1027 int64
1028 MediaNodesDataSource::NextValue(SystemInfo& info)
1029 {
1030 	return info.MediaNodes();
1031 }
1032 
1033 
1034 const char*
1035 MediaNodesDataSource::Label() const
1036 {
1037 	return "Media Nodes";
1038 }
1039 
1040 
1041 bool
1042 MediaNodesDataSource::AdaptiveScale() const
1043 {
1044 	return true;
1045 }
1046 
1047 
1048