Merge branch 'scheduler'
Conflicts: build/jam/packages/Haiku headers/os/kernel/OS.h headers/os/opengl/GLRenderer.h headers/private/shared/cpu_type.h src/add-ons/kernel/drivers/power/acpi_battery/acpi_battery.h src/bin/sysinfo.cpp src/bin/top.c src/system/kernel/arch/x86/arch_system_info.cpp src/system/kernel/port.cpp
This commit is contained in:
commit
d0f2d8282f
@ -53,7 +53,7 @@ SYSTEM_APPS = [ FFilterByBuildFeatures
|
||||
SoundRecorder StyledEdit Terminal TextSearch TV WebWatch Workspaces
|
||||
] ;
|
||||
SYSTEM_PREFERENCES = [ FFilterByBuildFeatures
|
||||
Appearance Backgrounds CPUFrequency DataTranslations
|
||||
Appearance Backgrounds DataTranslations
|
||||
<preference>Deskbar E-mail FileTypes Keyboard Keymap Locale Media
|
||||
Mouse Network Notifications Printers Screen ScreenSaver
|
||||
Shortcuts Sounds Time Touchpad <preference>Tracker VirtualMemory
|
||||
|
@ -53,7 +53,7 @@ SYSTEM_APPS = [ FFilterByBuildFeatures
|
||||
StyledEdit Terminal TextSearch Workspaces
|
||||
] ;
|
||||
SYSTEM_PREFERENCES = [ FFilterByBuildFeatures
|
||||
Appearance Backgrounds CPUFrequency
|
||||
Appearance Backgrounds
|
||||
<preference>Deskbar FileTypes Keyboard Keymap Locale
|
||||
Mouse Network Notifications Screen ScreenSaver
|
||||
Shortcuts Time Touchpad <preference>Tracker VirtualMemory
|
||||
|
@ -52,6 +52,8 @@ AddFilesToPackage add-ons kernel generic
|
||||
AddFilesToPackage add-ons kernel partitioning_systems
|
||||
: amiga_rdb apple efi_gpt intel session ;
|
||||
AddFilesToPackage add-ons kernel interrupt_controllers : openpic@ppc ;
|
||||
AddFilesToPackage add-ons kernel power cpufreq : intel_pstates@x86,x86_64 ;
|
||||
AddFilesToPackage add-ons kernel power cpuidle : intel_cstates@x86,x86_64 ;
|
||||
|
||||
if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
|
||||
AddFilesToPackage add-ons kernel cpu : generic_x86 ;
|
||||
@ -60,7 +62,6 @@ if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
|
||||
# drivers
|
||||
AddNewDriversToPackage disk scsi : scsi_cd scsi_disk ;
|
||||
AddNewDriversToPackage disk virtual : virtio_block ;
|
||||
AddNewDriversToPackage power : enhanced_speedstep@x86 ;
|
||||
AddNewDriversToPackage power : $(SYSTEM_ADD_ONS_DRIVERS_POWER) ;
|
||||
#AddNewDriversToPackage display : display_controls@x86 ;
|
||||
|
||||
|
@ -51,6 +51,8 @@ AddFilesToPackage add-ons kernel generic
|
||||
AddFilesToPackage add-ons kernel partitioning_systems
|
||||
: amiga_rdb apple efi_gpt intel session ;
|
||||
AddFilesToPackage add-ons kernel interrupt_controllers : openpic@ppc ;
|
||||
AddFilesToPackage add-ons kernel power cpufreq : intel_pstates@x86,x86_64 ;
|
||||
AddFilesToPackage add-ons kernel power cpuidle : intel_cstates@x86,x86_64 ;
|
||||
|
||||
if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
|
||||
AddFilesToPackage add-ons kernel cpu : generic_x86 ;
|
||||
@ -59,7 +61,6 @@ if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
|
||||
# drivers
|
||||
AddNewDriversToPackage disk scsi : scsi_cd scsi_disk ;
|
||||
AddNewDriversToPackage disk virtual : virtio_block ;
|
||||
AddNewDriversToPackage power : enhanced_speedstep@x86 ;
|
||||
AddNewDriversToPackage power : acpi_battery@x86 ;
|
||||
#AddNewDriversToPackage display : display_controls@x86 ;
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
1 belarusian x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Так
|
||||
CPU frequency status view CPU Frequency View Паказнік стану частаты працэсара
|
||||
OK Status view ОК
|
||||
Set state Status view Пазначыць стан
|
||||
Defaults Pref Window Прадвызначаныя
|
||||
Install replicant into Deskbar CPU Frequency View Усталяваць рэплікант у Deskbar
|
||||
Quit Status view Выйсце
|
||||
High performance Status view Вышэйшая прадукцыйнасць
|
||||
Stepping policy CPU Frequency View Палітыка пакрокавай рэгуляцыі
|
||||
Dynamic performance Status view Дынамічная прадукцыйнасць
|
||||
Step up by CPU usage Color Step View Актывізаваць у залежнасьці ад занятасці працэсара
|
||||
Dynamic stepping CPU Frequency View Дынамічны рэжым пакрокавай рэгуляцыі
|
||||
Stepping policy: CPU Frequency View Палітыка пакрокавай рэгуляцыі:
|
||||
Integration time [ms]: CPU Frequency View Квант інтэграцыі [ms]:
|
||||
Open Speedstep preferences… Status view Паказаць наладкі Speedstep…
|
||||
Revert Pref Window Вярнуць
|
||||
Low energy Status view Экономия энергии
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Немагчыма запусціць канфігурацыйную праграму!\n\nКод памылкі:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU Frequency\n\tбыў распрацаваны Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Частата Працэсара
|
@ -1,18 +0,0 @@
|
||||
1 bulgarian x-vnd.Haiku-CPUFrequencyPref 1018039204
|
||||
Ok Status view Ок
|
||||
CPU frequency status view CPU Frequency View Статус на CPU честотата
|
||||
Set state Status view Изберете състояние
|
||||
Defaults Pref Window По подразбиране
|
||||
Install replicant into Deskbar CPU Frequency View Инсталирай репликант в Deskbar
|
||||
High performance Status view Висока производителност
|
||||
Stepping policy CPU Frequency View Постъпково изменение на частотата на CPU
|
||||
Dynamic performance Status view Динамична производителност
|
||||
Step up by CPU usage Color Step View Стъпка на производителност на CPU:
|
||||
Dynamic stepping CPU Frequency View Динамично изменение
|
||||
Stepping policy: CPU Frequency View Постъпково изменение на частотата на CPU:
|
||||
Integration time [ms]: CPU Frequency View Време на интеграция [мс]:
|
||||
Open Speedstep preferences… Status view Отвори постъпковите настройки
|
||||
Revert Pref Window Върни
|
||||
Low energy Status view Икономия на енергия
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Старта на CPU Frequency не се състоя.\n\nГрешка:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tе разработен от Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
@ -1,19 +0,0 @@
|
||||
1 czech x-vnd.Haiku-CPUFrequencyPref 3974849433
|
||||
CPU frequency status view CPU Frequency View Zobrazení statusu frekvence CPU
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tnapsal Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Původní
|
||||
Dynamic performance Status view Dynamický výkon
|
||||
Dynamic stepping CPU Frequency View Dynamické krokování
|
||||
High performance Status view Vysoký výkon
|
||||
Install replicant into Deskbar CPU Frequency View Instaloval replikant do Deskbaru
|
||||
Integration time [ms]: CPU Frequency View Integrační čas [ms]:
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Nepodařilo se otevřít nastavení frekvence CPU.\n\nChyba:
|
||||
Low energy Status view Nízká spotřeba
|
||||
Ok Status view Ok
|
||||
Open Speedstep preferences… Status view Otevřít nastavení SpeedStep...
|
||||
Quit Status view Odejít
|
||||
Revert Pref Window Obnovit
|
||||
Set state Status view Nastavit stav
|
||||
Step up by CPU usage Color Step View Krokovat podle využití CPU
|
||||
Stepping policy CPU Frequency View Krokovací politika
|
||||
Stepping policy: CPU Frequency View Krokovací politika:
|
@ -1,19 +0,0 @@
|
||||
1 danish x-vnd.Haiku-CPUFrequencyPref 3974849433
|
||||
CPU frequency status view CPU Frequency View CPU frekvens statusoversigt
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrekvens\n\tskrevet af Clemens Zeidler\n\tOphavsret 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Standard indstillinger
|
||||
Dynamic performance Status view Dynamisk ydeevne
|
||||
Dynamic stepping CPU Frequency View Dynamisk acceleration
|
||||
High performance Status view Høj ydeevne
|
||||
Install replicant into Deskbar CPU Frequency View Indsæt replikant i Deskbar
|
||||
Integration time [ms]: CPU Frequency View Integrationstid [ms]:
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Det var ikke muligt at starte CPU frekvens indstillings programmet.\n\nFejl:
|
||||
Low energy Status view Lavt energiforbrug
|
||||
Ok Status view OK
|
||||
Open Speedstep preferences… Status view Åben Speedstep egenskaber…
|
||||
Quit Status view Afslut
|
||||
Revert Pref Window Tilbagestil
|
||||
Set state Status view Sæt tilstand
|
||||
Step up by CPU usage Color Step View Acceleration efter CPU belastning
|
||||
Stepping policy CPU Frequency View Accelerationspolitik
|
||||
Stepping policy: CPU Frequency View Accelerationspolitik:
|
@ -1,21 +0,0 @@
|
||||
1 german x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view OK
|
||||
CPU frequency status view CPU Frequency View CPU-Takt-Anzeige
|
||||
OK Status view OK
|
||||
Set state Status view Fester Takt
|
||||
Defaults Pref Window Standardwerte
|
||||
Install replicant into Deskbar CPU Frequency View Replikant in Deskbar installieren
|
||||
Quit Status view Beenden
|
||||
High performance Status view Hohe Leistung
|
||||
Stepping policy CPU Frequency View Taktungsrichtlinie
|
||||
Dynamic performance Status view Dynamische Leistung
|
||||
Step up by CPU usage Color Step View Taktänderung ab CPU-Auslastung von:
|
||||
Dynamic stepping CPU Frequency View Dynamische Taktung
|
||||
Stepping policy: CPU Frequency View Taktungsrichtlinie:
|
||||
Integration time [ms]: CPU Frequency View Messintervall [ms]:
|
||||
Open Speedstep preferences… Status view Speedstep Einstellungen öffnen…
|
||||
Revert Pref Window Anfangswerte
|
||||
Low energy Status view Geringer Energieverbrauch
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Das CPU-Takt-Preflet konnte nicht gestartet werden.\n\nFehler:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU-Takt\n\tGeschrieben von Clemens Zeidler.\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name CPU-Takt
|
@ -1,20 +0,0 @@
|
||||
1 greek, modern (1453-) x-vnd.Haiku-CPUFrequencyPref 3079996868
|
||||
Ok Status view Εντάξει
|
||||
CPU frequency status view CPU Frequency View Συχνότητα επεξεργαστή προβολή κατάστασης
|
||||
Set state Status view Ορισμός κατάστασης
|
||||
Defaults Pref Window Προεπιλογές
|
||||
Install replicant into Deskbar CPU Frequency View Εγκατάσταση αντίγραφου στη Μπάρα εργασιών
|
||||
Quit Status view Έξοδος
|
||||
High performance Status view Υψηλή επίδοση
|
||||
Stepping policy CPU Frequency View Πολιτική βηματισμού
|
||||
Dynamic performance Status view Δυναμική επίδοση
|
||||
Step up by CPU usage Color Step View Αύξηση με χρήση της CPU
|
||||
Dynamic stepping CPU Frequency View Δυναμικός βηματισμός
|
||||
Stepping policy: CPU Frequency View Πολιτική βηματισμού:
|
||||
Integration time [ms]: CPU Frequency View Χρόνος ολοκλήρωσης [ms]:
|
||||
Open Speedstep preferences… Status view Άνοιγμα προτιμήσεων Ταχύτητα βήματος
|
||||
Revert Pref Window Επαναφορά
|
||||
Low energy Status view Χαμηλή ενέργεια
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Απέτυχε η εκκίνηση του preflet Συχνότητα επεξεργαστή.\n\nΣφάλμα:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Συχνότητα Επεξεργαστή\n\tγράφτηκε από τον Clemens Zeidler\n\tΠνευματικά δικαιώματα 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Συχνότητα της CPU
|
@ -1,19 +0,0 @@
|
||||
1 esperanto x-vnd.Haiku-CPUFrequencyPref 3974849433
|
||||
CPU frequency status view CPU Frequency View Procesorofteca stato
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Procesorofteco\n\tskribita per Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Aprioraj
|
||||
Dynamic performance Status view Dinamika rendimento
|
||||
Dynamic stepping CPU Frequency View Dinamika akcelo
|
||||
High performance Status view Plejbona rendimento
|
||||
Install replicant into Deskbar CPU Frequency View Instali la kopianton en la Deskbar-on
|
||||
Integration time [ms]: CPU Frequency View Integralada tempo [ms]:
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Malsukcesis lanĉi la procesorofteca prefileto.\n\nEraro:
|
||||
Low energy Status view Malgranda energio
|
||||
Ok Status view Bone
|
||||
Open Speedstep preferences… Status view Malfermi la Speedstep-ajn agordojn…
|
||||
Quit Status view Eliri
|
||||
Revert Pref Window Malfari
|
||||
Set state Status view Ŝanĝi staton
|
||||
Step up by CPU usage Color Step View Akcelo per procesora uzo:
|
||||
Stepping policy CPU Frequency View Akcela reĝimo
|
||||
Stepping policy: CPU Frequency View Akcela reĝimo:
|
@ -1,21 +0,0 @@
|
||||
1 finnish x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Valmis
|
||||
CPU frequency status view CPU Frequency View Suoritintaajuuden tilanäkymä
|
||||
OK Status view Valmis
|
||||
Set state Status view Aseta tila
|
||||
Defaults Pref Window Oletukset
|
||||
Install replicant into Deskbar CPU Frequency View Asenna kopio Työpöytäpalkkiin
|
||||
Quit Status view Poistu
|
||||
High performance Status view Korkea suorituskyky
|
||||
Stepping policy CPU Frequency View Muutostapa
|
||||
Dynamic performance Status view Dynaaminen suorituskyky
|
||||
Step up by CPU usage Color Step View Muuta ylöspäin tämän suorittimen käyttömäärän kohdalla:
|
||||
Dynamic stepping CPU Frequency View Dynaaminen muutos
|
||||
Stepping policy: CPU Frequency View Muutostapa:
|
||||
Integration time [ms]: CPU Frequency View Integraatioaika [ms]:
|
||||
Open Speedstep preferences… Status view Avaa nopeusaskelvalinnat...
|
||||
Revert Pref Window Palauta
|
||||
Low energy Status view Matala energiankulutus
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Suoritintaajuuden asetusohjelman käynnistys epäonnistui.\n\nVirhe:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Suoritintaajuusasetukset\n\t tekijä: Clemens Zeidler\n\t Copyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Suoritintaajuusasetukset
|
@ -1,21 +0,0 @@
|
||||
1 french x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Ok
|
||||
CPU frequency status view CPU Frequency View Vue de l'état de la fréquence du CPU
|
||||
OK Status view OK
|
||||
Set state Status view Changer l'état
|
||||
Defaults Pref Window Par défauts
|
||||
Install replicant into Deskbar CPU Frequency View Installer le réplicant dans la Deskbar
|
||||
Quit Status view Quitter
|
||||
High performance Status view Haute performance
|
||||
Stepping policy CPU Frequency View Stratégie d'accélération
|
||||
Dynamic performance Status view Performance dynamique
|
||||
Step up by CPU usage Color Step View Accélération selon l'activité CPU
|
||||
Dynamic stepping CPU Frequency View Accélération dynamique
|
||||
Stepping policy: CPU Frequency View Stratégie d'accélération :
|
||||
Integration time [ms]: CPU Frequency View Temps d'intégration [ms] :
|
||||
Open Speedstep preferences… Status view Ouvrir les préférences Speestep…
|
||||
Revert Pref Window Rétablir
|
||||
Low energy Status view Basse consommation
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Échec de lancement des préférences de fréquence du CPU.\n\nErreur :
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Fréquence CPU\n\tÉcrit par Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Fréquence CPU
|
@ -1,20 +0,0 @@
|
||||
1 hindi x-vnd.Haiku-CPUFrequencyPref 3079996868
|
||||
Ok Status view ठीक है
|
||||
CPU frequency status view CPU Frequency View सीपियु आवृत्ति स्थिति देखने के लिए
|
||||
Set state Status view सेट स्टेट
|
||||
Defaults Pref Window डिफ़ॉल्ट्स
|
||||
Install replicant into Deskbar CPU Frequency View डेस्कबार में स्थापित रेप्लिका
|
||||
Quit Status view छोड़ना
|
||||
High performance Status view उच्च निष्पादन
|
||||
Stepping policy CPU Frequency View कदम नीति
|
||||
Dynamic performance Status view गतिशील प्रदर्शन
|
||||
Step up by CPU usage Color Step View धीरे-धीरे सीपियु का उपयोग द्वारा चरण होना
|
||||
Dynamic stepping CPU Frequency View गतिशील कदम
|
||||
Stepping policy: CPU Frequency View कदम नीति:
|
||||
Integration time [ms]: CPU Frequency View एकीकरण समय [एमएस]:
|
||||
Open Speedstep preferences… Status view खुला स्पीद्स्तेप वरीयता ...
|
||||
Revert Pref Window पलटें
|
||||
Low energy Status view कम इनरजी
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view लौन्चिंग सीपियु आवृत्ति शुभारंभ विफल.\n\nत्रुटि:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view सीपियु रेक़ुएन्क्य\n\t क्लेमेंस ज़िल्डर द्वारा त्व्रित्तें\n\t कोप्य्रिघ्त 2009, हाइकू, Inc.\n
|
||||
CPUFrequency System name सीपियु की आवृत्ति
|
@ -1,12 +0,0 @@
|
||||
1 croatian x-vnd.Haiku-CPUFrequencyPref 2355894194
|
||||
CPU frequency status view CPU Frequency View Pogled stanja frekvencije procesora
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Frekvencija procesora\n\tnapisao Clemens Zeidler\n\tAutoraska prava 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Zadano
|
||||
Dynamic performance Status view Dinamične performanse
|
||||
High performance Status view Visoke performanse
|
||||
Integration time [ms]: CPU Frequency View Vrijeme integracije [ms]:
|
||||
Ok Status view U redu
|
||||
Open Speedstep preferences… Status view Otvori Speedstep osobitosti...
|
||||
Quit Status view Isključi
|
||||
Revert Pref Window Preokreni
|
||||
Set state Status view Postavi stanje
|
@ -1,21 +0,0 @@
|
||||
1 hungarian x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Rendben
|
||||
CPU frequency status view CPU Frequency View Processzor-frekvencia állapota
|
||||
OK Status view Rendben
|
||||
Set state Status view Órajel beállítása
|
||||
Defaults Pref Window Eredeti
|
||||
Install replicant into Deskbar CPU Frequency View Replikáns telepítése az Asztalsávba
|
||||
Quit Status view Kilépés
|
||||
High performance Status view Nagy teljesítmény
|
||||
Stepping policy CPU Frequency View Fokozatszabályozás
|
||||
Dynamic performance Status view Dinamikus teljesítmény
|
||||
Step up by CPU usage Color Step View Kiegyensúlyozott teljesítmény
|
||||
Dynamic stepping CPU Frequency View Szabadon választható fokozatok
|
||||
Stepping policy: CPU Frequency View Fokozatszabályozás:
|
||||
Integration time [ms]: CPU Frequency View Alkalmazkodás ideje [ms]:
|
||||
Open Speedstep preferences… Status view Fokozatszabályozási beállító megnyitása…
|
||||
Revert Pref Window Visszaállít
|
||||
Low energy Status view Alacsony energiafogyasztás
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Nem sikerült a Processzor-frekvencia elindítása.\n\nHiba:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Processzor-frekvencia\n\tÍrta: Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Processzor-frekvencia
|
@ -1,19 +0,0 @@
|
||||
1 italian x-vnd.Haiku-CPUFrequencyPref 3974849433
|
||||
CPU frequency status view CPU Frequency View Stato frequenza della CPU
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Frequenza CPU\n\tscritto da Clemens Zeidler\n\tDiritti d'autore ©2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Predefiniti
|
||||
Dynamic performance Status view Prestazioni dinamiche
|
||||
Dynamic stepping CPU Frequency View Scalabilità dinamica
|
||||
High performance Status view Prestazioni elevate
|
||||
Install replicant into Deskbar CPU Frequency View Installa il replicante nella Deskbar
|
||||
Integration time [ms]: CPU Frequency View Tempo di intervento [ms]:
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Impossibile far partire le preferenze frequenza CPU.\n\nErrore:
|
||||
Low energy Status view Bassi consumi
|
||||
Ok Status view Ok
|
||||
Open Speedstep preferences… Status view Apri preferenze Speedstep…
|
||||
Quit Status view Esci
|
||||
Revert Pref Window Ripristina
|
||||
Set state Status view Imposta stato
|
||||
Step up by CPU usage Color Step View Scala in base all'utilizzo della CPU
|
||||
Stepping policy CPU Frequency View Regole di scalabilità
|
||||
Stepping policy: CPU Frequency View Regola scalabilità:
|
@ -1,21 +0,0 @@
|
||||
1 japanese x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Ok
|
||||
CPU frequency status view CPU Frequency View CPU 周波数ビュー
|
||||
OK Status view OK
|
||||
Set state Status view 設定
|
||||
Defaults Pref Window デフォルト
|
||||
Install replicant into Deskbar CPU Frequency View レプリカントを Deskbar に表示
|
||||
Quit Status view 終了
|
||||
High performance Status view ハイパフォーマンス
|
||||
Stepping policy CPU Frequency View ステッピングポリシー
|
||||
Dynamic performance Status view ダイナミックパフォーマンス
|
||||
Step up by CPU usage Color Step View CPU 負荷に応じてステップアップ
|
||||
Dynamic stepping CPU Frequency View ダイナミックステッピング
|
||||
Stepping policy: CPU Frequency View ステッピングポリシー
|
||||
Integration time [ms]: CPU Frequency View 積分時間 [ms]:
|
||||
Open Speedstep preferences… Status view Open Speedstep の設定…
|
||||
Revert Pref Window 元に戻す
|
||||
Low energy Status view 省電力モード
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view CPU 周波数の起動に失敗しました。\n\nエラー:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU 周波数\n\tClemens Zeidler 作\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name CPU 周波数
|
@ -1,19 +0,0 @@
|
||||
1 korean x-vnd.Haiku-CPUFrequencyPref 3974849433
|
||||
CPU frequency status view CPU Frequency View CPU 주파수 상태 보기
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU주파수\n\tClemens Zeidler 작성\n\t저작권 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window 기본설정
|
||||
Dynamic performance Status view 동적 성능
|
||||
Dynamic stepping CPU Frequency View 동적 스테핑
|
||||
High performance Status view 고성능
|
||||
Install replicant into Deskbar CPU Frequency View 데스크바에 복제품 설치
|
||||
Integration time [ms]: CPU Frequency View 통합 시간 [ms]:
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view CPU 주파수 제어판 불러오기 실패.\n\n에러:
|
||||
Low energy Status view 저전력
|
||||
Ok Status view 확인
|
||||
Open Speedstep preferences… Status view 스피드스텝 설정 열기…
|
||||
Quit Status view 나가기
|
||||
Revert Pref Window 되돌리기
|
||||
Set state Status view 상태 설정
|
||||
Step up by CPU usage Color Step View CPU 사용량에 따라 증가
|
||||
Stepping policy CPU Frequency View 스테핑 정책
|
||||
Stepping policy: CPU Frequency View 스테핑 정책:
|
@ -1,21 +0,0 @@
|
||||
1 lithuanian x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Gerai
|
||||
CPU frequency status view CPU Frequency View Centrinio procesoriaus dažnio indikatorius
|
||||
OK Status view Gerai
|
||||
Set state Status view Pasirinkta būsena
|
||||
Defaults Pref Window Numatytai
|
||||
Install replicant into Deskbar CPU Frequency View Patalpinti indikatorių pranešimų srityje
|
||||
Quit Status view Baigti darbą
|
||||
High performance Status view Didelis našumas
|
||||
Stepping policy CPU Frequency View Centrinio procesoriaus veiksena
|
||||
Dynamic performance Status view Prisitaikantis našumas
|
||||
Step up by CPU usage Color Step View Našumo keitimo žingsnis
|
||||
Dynamic stepping CPU Frequency View Prisitaikančio našumo derinimas
|
||||
Stepping policy: CPU Frequency View Centrinio procesoriaus veiksena:
|
||||
Integration time [ms]: CPU Frequency View Integravimosi laikas [ms]:
|
||||
Open Speedstep preferences… Status view CP dažnio nuostatos…
|
||||
Revert Pref Window Atšaukti pakeitimus
|
||||
Low energy Status view Energijos taupymas
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Nepavyko atverti Centrinio procesoriaus dažnio nuostatų lango.\n\nKlaida:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Centrinio procesoriaus dažnis\n\tsukurtas Clemens'o Zeidler'io\n\t© 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Centrinio procesoriaus dažnis
|
@ -1,19 +0,0 @@
|
||||
1 bokmål, norwegian; norwegian bokmål x-vnd.Haiku-CPUFrequencyPref 1579805342
|
||||
Ok Status view OK
|
||||
CPU frequency status view CPU Frequency View Visning av CPU-status
|
||||
Set state Status view Sett tilstand
|
||||
Defaults Pref Window Standardinnstillinger
|
||||
Install replicant into Deskbar CPU Frequency View Installer replikanten i Deskbar
|
||||
Quit Status view Avslutt
|
||||
High performance Status view Høy ytelse
|
||||
Stepping policy CPU Frequency View Stepping-policy
|
||||
Dynamic performance Status view Dynamisk ytelse
|
||||
Dynamic stepping CPU Frequency View Dynamisk stepping
|
||||
Stepping policy: CPU Frequency View Stepping-policy
|
||||
Integration time [ms]: CPU Frequency View Integrasjonstid [ms]:
|
||||
Open Speedstep preferences… Status view Åpne Speedstep-innstillinger
|
||||
Revert Pref Window Tilbakestill
|
||||
Low energy Status view Lavenergi
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Feil ved lasting av Prosessorhastighet. \n\nFeil:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tskrevet av Clemens Zeidler\n\tOpphavsrett 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Prosessorhastighet
|
@ -1,21 +0,0 @@
|
||||
1 dutch; flemish x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Oké
|
||||
CPU frequency status view CPU Frequency View Weergave CPU-frequentiestatus
|
||||
OK Status view Ok
|
||||
Set state Status view Toestand instellen
|
||||
Defaults Pref Window Standaardwaarden
|
||||
Install replicant into Deskbar CPU Frequency View Replicant in Deskbar installeren
|
||||
Quit Status view Afsluiten
|
||||
High performance Status view Hoge prestaties
|
||||
Stepping policy CPU Frequency View Stapbeleid
|
||||
Dynamic performance Status view Dynamische prestaties
|
||||
Step up by CPU usage Color Step View Opvoeren door CPU-gebruik
|
||||
Dynamic stepping CPU Frequency View Dynamisch opvoeren
|
||||
Stepping policy: CPU Frequency View Opvoerbeleid:
|
||||
Integration time [ms]: CPU Frequency View Integratietijd [ms]:
|
||||
Open Speedstep preferences… Status view Speedstep-voorkeuren openen…
|
||||
Revert Pref Window Herstellen
|
||||
Low energy Status view Lage energie
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Starten van de CPU-frequentiepreflet is mislukt.\n\nFout:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tdoor Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name CPUFrequency
|
@ -1,21 +0,0 @@
|
||||
1 polish x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Ok
|
||||
CPU frequency status view CPU Frequency View Widok statusu częstotliwości taktowania procesora
|
||||
OK Status view OK
|
||||
Set state Status view Ustaw stan
|
||||
Defaults Pref Window Przywróć ustawienia domyślne
|
||||
Install replicant into Deskbar CPU Frequency View Zainstaluj replikant na Panelu Pulpitu
|
||||
Quit Status view Zamknij
|
||||
High performance Status view Wysoka wydajność
|
||||
Stepping policy CPU Frequency View Polityka skalowania procesora
|
||||
Dynamic performance Status view Dynamicznie dopasowana wydajność
|
||||
Step up by CPU usage Color Step View Ustawiaj taktowanie w zależności od obciążenia procesora
|
||||
Dynamic stepping CPU Frequency View Dynamiczne skalowanie
|
||||
Stepping policy: CPU Frequency View Polityka skalowania:
|
||||
Integration time [ms]: CPU Frequency View Czas integracji (w milisekundach):
|
||||
Open Speedstep preferences… Status view Otwórz ustawienia Speedstep…
|
||||
Revert Pref Window Przywróć poprzednie ustawienia
|
||||
Low energy Status view Oszczędna
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Uruchomienie prefletu częstotliwości procesora zakończyło się niepowodzeniem.\n\nBłąd:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tnapisane przez Clemensa Zeidlera\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Częstotliwość procesora
|
@ -1,12 +0,0 @@
|
||||
1 portuguese x-vnd.Haiku-CPUFrequencyPref 2133997991
|
||||
Defaults Pref Window Predefenições
|
||||
Dynamic stepping CPU Frequency View Aceleração Dinâmica
|
||||
Install replicant into Deskbar CPU Frequency View Instalar o Replicant na Deskbar
|
||||
Integration time [ms]: CPU Frequency View Tempo de integração [ms]:
|
||||
Ok Status view OK
|
||||
Quit Status view Sair
|
||||
Revert Pref Window Reverter
|
||||
Set state Status view Defenir estado
|
||||
Step up by CPU usage Color Step View Variação de velocidade com base no uso do CPU
|
||||
Stepping policy CPU Frequency View Política de Aceleração
|
||||
Stepping policy: CPU Frequency View Política de Aceleração:
|
@ -1,21 +0,0 @@
|
||||
1 portuguese (brazil) x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view Ok
|
||||
CPU frequency status view CPU Frequency View Status da frequência do CPU
|
||||
OK Status view OK
|
||||
Set state Status view Definir estado
|
||||
Defaults Pref Window Padrões
|
||||
Install replicant into Deskbar CPU Frequency View Instalar o replicante na Mesa de Trabalho
|
||||
Quit Status view Sair
|
||||
High performance Status view Alto desempenho
|
||||
Stepping policy CPU Frequency View Política de stepping
|
||||
Dynamic performance Status view Desempenho dinâmico
|
||||
Step up by CPU usage Color Step View Aumentar desempenho por uso de CPU
|
||||
Dynamic stepping CPU Frequency View Stepping dinâmico
|
||||
Stepping policy: CPU Frequency View Política de stepping:
|
||||
Integration time [ms]: CPU Frequency View Tempo de integração [ms]:
|
||||
Open Speedstep preferences… Status view Preferências de Open Speedstep…
|
||||
Revert Pref Window Reverter
|
||||
Low energy Status view Baixa energia
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Não foi possível abrir a Frequência de CPU.\n\nErro:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view A Frequência do CPU\n\tfoi escrito por Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Frequência do CPU
|
@ -1,8 +0,0 @@
|
||||
1 brazilian_portuguese x-vnd.Haiku-CPUFrequencyPref 1149286520
|
||||
CPU frequency status view CPU Frequency View Status da frequência do CPU
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view A Frequência do CPU\n\tfoi escrito por Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
Defaults Pref Window Padrões
|
||||
Install replicant into Deskbar CPU Frequency View Instalar o replicante na Mesa de Trabalho
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Não foi possível abrir a Frequência de CPU.\n\nErro:
|
||||
Low energy Status view Baixa energia
|
||||
Set state Status view Definir estado
|
@ -1,20 +0,0 @@
|
||||
1 romanian x-vnd.Haiku-CPUFrequencyPref 3079996868
|
||||
Ok Status view Ok
|
||||
CPU frequency status view CPU Frequency View Vizualizare a stării frecvenței CPU
|
||||
Set state Status view Stabilește stare
|
||||
Defaults Pref Window Implicite
|
||||
Install replicant into Deskbar CPU Frequency View Instalează copie pe Deskbar
|
||||
Quit Status view Părăsește
|
||||
High performance Status view Performanță înaltă
|
||||
Stepping policy CPU Frequency View Regulă de accelerare
|
||||
Dynamic performance Status view Performanță dinamică
|
||||
Step up by CPU usage Color Step View Accelerare după utilizarea CPU
|
||||
Dynamic stepping CPU Frequency View Accelerare dinamică
|
||||
Stepping policy: CPU Frequency View Regulă de accelerare:
|
||||
Integration time [ms]: CPU Frequency View Timp de integrare [ms]:
|
||||
Open Speedstep preferences… Status view Deschide preferințe viteză…
|
||||
Revert Pref Window Revenire
|
||||
Low energy Status view Energie scăzută
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Pornirea prefletului frecvență CPU a eșuat.\n\nEroare:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view FrecvențăCPU\n\tscris de Clemens Zeidler\n\tDrept de autor 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name FrecvențăCPU
|
@ -1,21 +0,0 @@
|
||||
1 russian x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view ОК
|
||||
CPU frequency status view CPU Frequency View Просмотр состояния частоты ЦП
|
||||
OK Status view OK
|
||||
Set state Status view Выбрать состояние
|
||||
Defaults Pref Window По умолчанию
|
||||
Install replicant into Deskbar CPU Frequency View Установить репликант в Deskbar
|
||||
Quit Status view Выход
|
||||
High performance Status view Высокая производительность
|
||||
Stepping policy CPU Frequency View Настройка шага изменения частоты ЦП
|
||||
Dynamic performance Status view Динамическая производительность
|
||||
Step up by CPU usage Color Step View Шаг вверх по производительности ЦП:
|
||||
Dynamic stepping CPU Frequency View Динамическое изменение
|
||||
Stepping policy: CPU Frequency View Настройка шага изменения частоты ЦП:
|
||||
Integration time [ms]: CPU Frequency View Время интеграции [мс]:
|
||||
Open Speedstep preferences… Status view Настроить частоту процессора…
|
||||
Revert Pref Window Вернуть
|
||||
Low energy Status view Экономия энергии
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Не удалось запустить настройки частоты ЦП.\n\nОшибка:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tразработал Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Частота процессора
|
@ -1,21 +0,0 @@
|
||||
1 slovak x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view OK
|
||||
CPU frequency status view CPU Frequency View Zobrazenie stavy frekvencie CPU
|
||||
OK Status view OK
|
||||
Set state Status view Nastaviť stav
|
||||
Defaults Pref Window Predvoľby
|
||||
Install replicant into Deskbar CPU Frequency View Nainštalovať replikant do Panelu
|
||||
Quit Status view Ukončiť
|
||||
High performance Status view Vysoký výkon
|
||||
Stepping policy CPU Frequency View Politika krokovania
|
||||
Dynamic performance Status view Dynamický výkon
|
||||
Step up by CPU usage Color Step View Krokovať podľa využitia CPU
|
||||
Dynamic stepping CPU Frequency View Dynamické krokovanie
|
||||
Stepping policy: CPU Frequency View Politika krokovania:
|
||||
Integration time [ms]: CPU Frequency View Čas integrácie [ms]:
|
||||
Open Speedstep preferences… Status view Otvoriť nastavenia Speedstep…
|
||||
Revert Pref Window Vrátiť
|
||||
Low energy Status view Nízky odber
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Spustenie konfiguračného apletu Frekvencia CPU zlyhalo.\n\nChyba:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPUFrequency\n\tnapísal Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Frekvencia CPU
|
@ -1,21 +0,0 @@
|
||||
1 swedish x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view OK
|
||||
CPU frequency status view CPU Frequency View Statusvy för ProcessorFrekvens
|
||||
OK Status view OK
|
||||
Set state Status view Ändra läge
|
||||
Defaults Pref Window Förval
|
||||
Install replicant into Deskbar CPU Frequency View Installera replikant i Deskbar
|
||||
Quit Status view Avsluta
|
||||
High performance Status view Hög prestanda
|
||||
Stepping policy CPU Frequency View Accelerationspolicy
|
||||
Dynamic performance Status view Dynamisk prestanda
|
||||
Step up by CPU usage Color Step View Öka vid CPU-belastning
|
||||
Dynamic stepping CPU Frequency View Dynamisk acceleration
|
||||
Stepping policy: CPU Frequency View Accelerationspolicy:
|
||||
Integration time [ms]: CPU Frequency View Integreringstid
|
||||
Open Speedstep preferences… Status view Öppna inställningar för ProcessorFrekvens…
|
||||
Revert Pref Window Återgå
|
||||
Low energy Status view Lågenergiläge
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Misslyckades med att starta inställningsprogrammet ProcessorFrekvens.\n\nFel:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view ProcessorFrekvens\n\tskriven av Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name ProcessorFrekvens
|
@ -1,20 +0,0 @@
|
||||
1 ukrainian x-vnd.Haiku-CPUFrequencyPref 3079996868
|
||||
Ok Status view Гаразд
|
||||
CPU frequency status view CPU Frequency View Статистика частоти ЦП
|
||||
Set state Status view Встановити стан
|
||||
Defaults Pref Window По замовчуванню
|
||||
Install replicant into Deskbar CPU Frequency View Встановити реплікант в Deskbar
|
||||
Quit Status view Вийти
|
||||
High performance Status view Висока продуктивність
|
||||
Stepping policy CPU Frequency View Настройка кроку зміни частоти ЦП
|
||||
Dynamic performance Status view Динамічна продуктивність
|
||||
Step up by CPU usage Color Step View Крок вгору по продуктивності ЦП:
|
||||
Dynamic stepping CPU Frequency View Динамічна зміна
|
||||
Stepping policy: CPU Frequency View Настройка кроку зміни частоти ЦП:
|
||||
Integration time [ms]: CPU Frequency View Час інтеграції [мс]:
|
||||
Open Speedstep preferences… Status view Відкриття покрокової настройки
|
||||
Revert Pref Window Повернути
|
||||
Low energy Status view Мале споживання
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view Програму Частота процесора не вдалося запустити.\n\nПомилка:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view Частота процесора\n\Автор Клеменс Зейдлер\n\tCopyright 2009, Haiku, Inc.\n
|
||||
CPUFrequency System name Частота процесора
|
@ -1,20 +0,0 @@
|
||||
1 english x-vnd.Haiku-CPUFrequencyPref 3079996868
|
||||
Ok Status view 确定
|
||||
CPU frequency status view CPU Frequency View CPU 状态视图
|
||||
Set state Status view 状态设置
|
||||
Defaults Pref Window 默认
|
||||
Install replicant into Deskbar CPU Frequency View 添加 CPU 监视器到桌面栏
|
||||
Quit Status view 退出
|
||||
High performance Status view 高性能
|
||||
Stepping policy CPU Frequency View 步进策略
|
||||
Dynamic performance Status view 动态性能
|
||||
Step up by CPU usage Color Step View CPU 步进设置
|
||||
Dynamic stepping CPU Frequency View 动态步进
|
||||
Stepping policy: CPU Frequency View 步进策略:
|
||||
Integration time [ms]: CPU Frequency View 采样时间 [ms]:
|
||||
Open Speedstep preferences… Status view 打开省电设置…
|
||||
Revert Pref Window 取消
|
||||
Low energy Status view 低能耗
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view 启动 CPU 状态通知失败。\n\n错误信息:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU 监视器\n\t编写者:Clemens Zeidler\n\tCopyright 2009,Haiku .Inc。\n
|
||||
CPUFrequency System name CPU 监视器
|
@ -1,21 +0,0 @@
|
||||
1 english x-vnd.Haiku-CPUFrequencyPref 1007318924
|
||||
Ok Status view 确定
|
||||
CPU frequency status view CPU Frequency View CPU 状态视图
|
||||
OK Status view 确定
|
||||
Set state Status view 状态设置
|
||||
Defaults Pref Window 默认
|
||||
Install replicant into Deskbar CPU Frequency View 添加 CPU 监视器到桌面栏
|
||||
Quit Status view 退出
|
||||
High performance Status view 高性能
|
||||
Stepping policy CPU Frequency View 步进策略
|
||||
Dynamic performance Status view 动态性能
|
||||
Step up by CPU usage Color Step View CPU 步进设置
|
||||
Dynamic stepping CPU Frequency View 动态步进
|
||||
Stepping policy: CPU Frequency View 步进策略:
|
||||
Integration time [ms]: CPU Frequency View 采样时间 [ms]:
|
||||
Open Speedstep preferences… Status view 打开省电设置…
|
||||
Revert Pref Window 取消
|
||||
Low energy Status view 低能耗
|
||||
Launching the CPU frequency preflet failed.\n\nError: Status view 启动 CPU 状态通知失败。\n\n错误信息:
|
||||
CPUFrequency\n\twritten by Clemens Zeidler\n\tCopyright 2009, Haiku, Inc.\n Status view CPU 监视器\n\t编写者:Clemens Zeidler\n\tCopyright 2009,Haiku .Inc。\n
|
||||
CPUFrequency System name CPU 监视器
|
@ -627,15 +627,13 @@
|
||||
//! @{
|
||||
|
||||
|
||||
/*! \fn int32 atomic_set(vint32 *value, int32 newValue)
|
||||
/*! \fn void atomic_set(int32* value, int32 newValue)
|
||||
\brief Atomically set the variable \a value to \a newvalue.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c = \c newValue
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
|
||||
\return The original value of \c value.
|
||||
mutex in this case. The variable must be naturally aligned.
|
||||
|
||||
\sa atomic_set64() for a version that works on \c long \c long.
|
||||
\sa atomic_test_and_set()
|
||||
@ -646,7 +644,28 @@
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn int32 atomic_test_and_set(vint32 *value, int32 newValue,
|
||||
/*! \fn int32 atomic_get_and_set(int32* value, int32 newValue)
|
||||
\brief Atomically set the variable \a value to \a newvalue and return the
|
||||
old value.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c = \c newValue
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_get_and_set64() for a version that works on \c long \c long.
|
||||
\sa atomic_set()
|
||||
\sa atomic_test_and_set()
|
||||
\sa atomic_add()
|
||||
\sa atomic_and()
|
||||
\sa atomic_or(),
|
||||
\sa atomic_get()
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn int32 atomic_test_and_set(int32* value, int32 newValue,
|
||||
int32 testAgainst)
|
||||
\brief Atomically set the variable \a value to \a newValue if the current
|
||||
value is \a testAgainst.
|
||||
@ -659,6 +678,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_test_and_set64() for a version that works on \c long \c long.
|
||||
\sa atomic_get_and_set()
|
||||
\sa atomic_set()
|
||||
\sa atomic_add()
|
||||
\sa atomic_and()
|
||||
@ -668,7 +688,7 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int32 atomic_add(vint32 *value, int32 addValue)
|
||||
\fn int32 atomic_add(int32* value, int32 addValue)
|
||||
\brief Atomically add the value of \a addValue to \a value.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c += \c addValue
|
||||
@ -679,6 +699,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_add64() for a version that works on \c long \c long.
|
||||
\sa atomic_get_and_set()
|
||||
\sa atomic_set()
|
||||
\sa atomic_test_and_set()
|
||||
\sa atomic_and()
|
||||
@ -687,7 +708,7 @@
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn int32 atomic_and(vint32 *value, int32 andValue)
|
||||
/*! \fn int32 atomic_and(int32* value, int32 andValue)
|
||||
\brief Atomically perform a bitwise AND operation of \a andValue to the
|
||||
variable \a andValue.
|
||||
|
||||
@ -699,6 +720,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_and64() for a version that works on \c long \c long.
|
||||
\sa atomic_get_and_set()
|
||||
\sa atomic_set()
|
||||
\sa atomic_test_and_set()
|
||||
\sa atomic_add()
|
||||
@ -709,7 +731,7 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int32 atomic_or(vint32 *value, int32 orValue)
|
||||
\fn int32 atomic_or(int32* value, int32 orValue)
|
||||
\brief Atomically perform a bitwise OR operation of \a orValue to the
|
||||
variable \a andValue.
|
||||
|
||||
@ -721,6 +743,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_or64() for a version that works on \c long \c long.
|
||||
\sa atomic_get_and_set()
|
||||
\sa atomic_set()
|
||||
\sa atomic_test_and_set()
|
||||
\sa atomic_add()
|
||||
@ -730,17 +753,18 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int32 atomic_get(vint32 *value)
|
||||
\fn int32 atomic_get(int32* value)
|
||||
\brief Atomically return the value of \c value.
|
||||
|
||||
This is a thread-safe way of reading the contents of the \c value
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
mutex in this case. The variable must be naturally aligned.
|
||||
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_get64() for a version that works on \c long \c long.
|
||||
\sa atomic_get_and_set()
|
||||
\sa atomic_set()
|
||||
\sa atomic_test_and_set()
|
||||
\sa atomic_add()
|
||||
@ -750,17 +774,16 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_set64(vint64 *value, int64 newValue)
|
||||
\fn void atomic_set64(int64* value, int64 newValue)
|
||||
\brief Atomically set the variable \a value to \a newvalue.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c = \c newValue
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
|
||||
\return The original value of \c value.
|
||||
mutex in this case. The variable must be naturally aligned.
|
||||
|
||||
\sa atomic_set() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_add64()
|
||||
\sa atomic_and64()
|
||||
@ -770,7 +793,29 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_test_and_set64(vint64 *value, int64 newValue,
|
||||
\fn int64 atomic_get_and_set64(int64* value, int64 newValue)
|
||||
\brief Atomically set the variable \a value to \a newvalue and return
|
||||
the old value.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c = \c newValue
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_get_and_set() for a version that works on an \c int32.
|
||||
\sa atomic_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_add64()
|
||||
\sa atomic_and64()
|
||||
\sa atomic_or64()
|
||||
\sa atomic_get64()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_test_and_set64(int64* value, int64 newValue,
|
||||
int64 testAgainst)
|
||||
\brief Atomically set the variable \a value to \a newValue if the current
|
||||
value is \a testAgainst.
|
||||
@ -783,6 +828,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_test_and_set() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_set64()
|
||||
\sa atomic_add64()
|
||||
\sa atomic_and64()
|
||||
@ -792,7 +838,7 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_add64(vint64 *value, int64 addValue)
|
||||
\fn int64 atomic_add64(int64* value, int64 addValue)
|
||||
\brief Atomically add the value of \a addValue to \a value.
|
||||
|
||||
This is a thread-safe way of performing the \c *value \c += \c addValue
|
||||
@ -803,6 +849,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_add() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_and64()
|
||||
@ -812,7 +859,7 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_and64(vint64 *value, int64 andValue)
|
||||
\fn int64 atomic_and64(int64* value, int64 andValue)
|
||||
\brief Atomically perform a bitwise AND operation of \a andValue to the
|
||||
variable \a andValue.
|
||||
|
||||
@ -824,6 +871,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_and() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_add64()
|
||||
@ -832,7 +880,7 @@
|
||||
*/
|
||||
|
||||
|
||||
/*! \fn int64 atomic_or64(vint64 *value, int64 orValue)
|
||||
/*! \fn int64 atomic_or64(int64* value, int64 orValue)
|
||||
\brief Atomically perform a bitwise OR operation of \a orValue to the
|
||||
variable \a andValue.
|
||||
|
||||
@ -844,6 +892,7 @@
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_or() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_add64()
|
||||
@ -853,17 +902,18 @@
|
||||
|
||||
|
||||
/*!
|
||||
\fn int64 atomic_get64(vint64 *value)
|
||||
\fn int64 atomic_get64(int64* value)
|
||||
\brief Atomically return the value of \c value.
|
||||
|
||||
This is a thread-safe way of reading the contents of the \c value
|
||||
operation. You should use these function when two or more threads might
|
||||
access the variable simultaneously. You don't have to use a semaphore or a
|
||||
mutex in this case.
|
||||
mutex in this case. The variable must be naturally aligned.
|
||||
|
||||
\return The original value of \c value.
|
||||
|
||||
\sa atomic_get() for a version that works on an \c int32.
|
||||
\sa atomic_get_and_set64()
|
||||
\sa atomic_set64()
|
||||
\sa atomic_test_and_set64()
|
||||
\sa atomic_add64()
|
||||
|
@ -118,17 +118,19 @@ struct media_node;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int32 atomic_set(vint32 *value, int32 newValue);
|
||||
extern int32 atomic_test_and_set(vint32 *value, int32 newValue,
|
||||
extern void atomic_set(int32* value, int32 newValue);
|
||||
extern int32 atomic_get_and_set(int32* value, int32 newValue);
|
||||
extern int32 atomic_test_and_set(int32 *value, int32 newValue,
|
||||
int32 testAgainst);
|
||||
extern int32 atomic_get(vint32 *value);
|
||||
extern int64 atomic_set64(vint64 *value, int64 newValue);
|
||||
extern int64 atomic_test_and_set64(vint64 *value, int64 newValue,
|
||||
extern int32 atomic_get(int32 *value);
|
||||
extern void atomic_set64(int64* value, int64 newValue);
|
||||
extern int64 atomic_get_and_set64(int64* value, int64 newValue);
|
||||
extern int64 atomic_test_and_set64(int64 *value, int64 newValue,
|
||||
int64 testAgainst);
|
||||
extern int64 atomic_get64(vint64 *value);
|
||||
extern int64 atomic_add64(vint64 *value, int64 addValue);
|
||||
extern int64 atomic_and64(vint64 *value, int64 andValue);
|
||||
extern int64 atomic_or64(vint64 *value, int64 orValue);
|
||||
extern int64 atomic_get64(int64 *value);
|
||||
extern int64 atomic_add64(int64 *value, int64 addValue);
|
||||
extern int64 atomic_and64(int64 *value, int64 andValue);
|
||||
extern int64 atomic_or64(int64 *value, int64 orValue);
|
||||
|
||||
extern size_t strnlen(const char *string, size_t count);
|
||||
|
||||
|
@ -66,7 +66,7 @@ extern void __length_error (const char *);
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
extern "C" __haiku_int32 atomic_add(volatile __haiku_int32* value,
|
||||
extern "C" __haiku_int32 atomic_add(__haiku_int32* value,
|
||||
__haiku_int32 addvalue);
|
||||
#endif /* __HAIKU__ */
|
||||
|
||||
@ -82,7 +82,7 @@ private:
|
||||
charT* data () { return reinterpret_cast<charT *>(this + 1); }
|
||||
charT& operator[] (size_t s) { return data () [s]; }
|
||||
#ifdef __HAIKU__
|
||||
charT* grab () { if (selfish) return clone (); atomic_add((volatile __haiku_int32*) &ref, 1); return data (); }
|
||||
charT* grab () { if (selfish) return clone (); atomic_add((__haiku_int32*) &ref, 1); return data (); }
|
||||
void release() { if (atomic_add((__haiku_int32*) &ref, -1) == 1) delete this; }
|
||||
#else
|
||||
charT* grab () { if (selfish) return clone (); ++ref; return data (); }
|
||||
|
@ -20,9 +20,9 @@ typedef ulong cpu_status;
|
||||
|
||||
#if B_DEBUG_SPINLOCK_CONTENTION
|
||||
typedef struct {
|
||||
vint32 lock;
|
||||
vint32 count_low;
|
||||
vint32 count_high;
|
||||
int32 lock;
|
||||
int32 count_low;
|
||||
int32 count_high;
|
||||
} spinlock;
|
||||
|
||||
# define B_SPINLOCK_INITIALIZER { 0, 0, 0 }
|
||||
@ -31,15 +31,39 @@ typedef ulong cpu_status;
|
||||
(spinlock)->count_low = 0; \
|
||||
(spinlock)->count_high = 0; \
|
||||
} while (false)
|
||||
# define B_SPINLOCK_IS_LOCKED(spinlock) ((spinlock)->lock > 0)
|
||||
#else
|
||||
typedef vint32 spinlock;
|
||||
typedef struct {
|
||||
int32 lock;
|
||||
} spinlock;
|
||||
|
||||
# define B_SPINLOCK_INITIALIZER 0
|
||||
# define B_INITIALIZE_SPINLOCK(lock) do { *(lock) = 0; } while (false)
|
||||
# define B_SPINLOCK_IS_LOCKED(lock) (*(lock) > 0)
|
||||
# define B_SPINLOCK_INITIALIZER { 0 }
|
||||
# define B_INITIALIZE_SPINLOCK(spinlock) do { \
|
||||
(spinlock)->lock = 0; \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
#define B_SPINLOCK_IS_LOCKED(spinlock) (atomic_get(&(spinlock)->lock) > 0)
|
||||
|
||||
typedef struct {
|
||||
int32 lock;
|
||||
} rw_spinlock;
|
||||
|
||||
#define B_RW_SPINLOCK_INITIALIZER { 0 }
|
||||
#define B_INITIALIZE_RW_SPINLOCK(rw_spinlock) do { \
|
||||
(rw_spinlock)->lock = 0; \
|
||||
} while (false)
|
||||
|
||||
typedef struct {
|
||||
spinlock lock;
|
||||
uint32 count;
|
||||
} seqlock;
|
||||
|
||||
#define B_SEQLOCK_INITIALIZER { B_SPINLOCK_INITIALIZER, 0 }
|
||||
#define B_INITIALIZE_SEQLOCK(seqlock) do { \
|
||||
B_INITIALIZE_SPINLOCK(&(seqlock)->lock); \
|
||||
(seqlock)->count = 0; \
|
||||
} while (false)
|
||||
|
||||
/* interrupt handling support for device drivers */
|
||||
|
||||
typedef int32 (*interrupt_handler)(void *data);
|
||||
@ -126,6 +150,19 @@ extern void restore_interrupts(cpu_status status);
|
||||
extern void acquire_spinlock(spinlock *lock);
|
||||
extern void release_spinlock(spinlock *lock);
|
||||
|
||||
extern bool try_acquire_write_spinlock(rw_spinlock* lock);
|
||||
extern void acquire_write_spinlock(rw_spinlock* lock);
|
||||
extern void release_write_spinlock(rw_spinlock* lock);
|
||||
extern bool try_acquire_read_spinlock(rw_spinlock* lock);
|
||||
extern void acquire_read_spinlock(rw_spinlock* lock);
|
||||
extern void release_read_spinlock(rw_spinlock* lock);
|
||||
|
||||
extern bool try_acquire_write_seqlock(seqlock* lock);
|
||||
extern void acquire_write_seqlock(seqlock* lock);
|
||||
extern void release_write_seqlock(seqlock* lock);
|
||||
extern uint32 acquire_read_seqlock(seqlock* lock);
|
||||
extern bool release_read_seqlock(seqlock* lock, uint32 count);
|
||||
|
||||
extern status_t install_io_interrupt_handler(long interrupt_number,
|
||||
interrupt_handler handler, void *data, ulong flags);
|
||||
extern status_t remove_io_interrupt_handler(long interrupt_number,
|
||||
|
32
headers/os/drivers/cpufreq.h
Normal file
32
headers/os/drivers/cpufreq.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CPUFREQ_H
|
||||
#define _CPUFREQ_H
|
||||
|
||||
|
||||
#include <module.h>
|
||||
|
||||
#include <scheduler.h>
|
||||
|
||||
|
||||
#define CPUFREQ_MODULES_PREFIX "power/cpufreq"
|
||||
|
||||
|
||||
const int kCPUPerformanceScaleMax = 1000;
|
||||
|
||||
typedef struct cpufreq_module_info {
|
||||
module_info info;
|
||||
|
||||
float rank;
|
||||
|
||||
void (*cpufreq_set_scheduler_mode)(enum scheduler_mode mode);
|
||||
|
||||
status_t (*cpufreq_increase_performance)(int delta);
|
||||
status_t (*cpufreq_decrease_performance)(int delta);
|
||||
} cpufreq_module_info;
|
||||
|
||||
|
||||
#endif // _CPUFREQ_H
|
||||
|
@ -8,50 +8,22 @@
|
||||
|
||||
#include <module.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CPUIDLE_CSTATE_MAX 8
|
||||
#define CSTATE_NAME_LENGTH 32
|
||||
#define B_CPUIDLE_MODULE_NAME "generic/cpuidle/v1"
|
||||
#include <scheduler.h>
|
||||
|
||||
|
||||
struct CpuidleStat {
|
||||
uint64 usageCount;
|
||||
bigtime_t usageTime;
|
||||
};
|
||||
#define CPUIDLE_MODULES_PREFIX "power/cpuidle"
|
||||
|
||||
|
||||
struct CpuidleInfo {
|
||||
int32 cstateSleep;
|
||||
CpuidleStat stats[CPUIDLE_CSTATE_MAX];
|
||||
};
|
||||
typedef struct cpuidle_module_info {
|
||||
module_info info;
|
||||
|
||||
struct CpuidleDevice;
|
||||
float rank;
|
||||
|
||||
struct CpuidleCstate {
|
||||
char name[CSTATE_NAME_LENGTH];
|
||||
int32 latency;
|
||||
int32 (*EnterIdle)(int32 state, CpuidleDevice *device);
|
||||
void *pData;
|
||||
};
|
||||
void (*cpuidle_set_scheduler_mode)(enum scheduler_mode mode);
|
||||
|
||||
void (*cpuidle_idle)(void);
|
||||
void (*cpuidle_wait)(int32* variable, int32 test);
|
||||
} cpuidle_module_info;
|
||||
|
||||
struct CpuidleDevice {
|
||||
CpuidleCstate cStates[CPUIDLE_CSTATE_MAX];
|
||||
int32 cStateCount;
|
||||
};
|
||||
|
||||
|
||||
struct CpuidleModuleInfo {
|
||||
module_info info;
|
||||
status_t (*AddDevice)(CpuidleDevice *device);
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _CPUIDLE_MODULE_H
|
||||
|
@ -420,244 +420,108 @@ extern void ktrace_vprintf(const char *format, va_list args);
|
||||
|
||||
/* System information */
|
||||
|
||||
#if __INTEL__
|
||||
# define B_MAX_CPU_COUNT 8
|
||||
#elif __x86_64__
|
||||
# define B_MAX_CPU_COUNT 8
|
||||
#elif __POWERPC__
|
||||
# define B_MAX_CPU_COUNT 8
|
||||
#elif __M68K__
|
||||
# define B_MAX_CPU_COUNT 1
|
||||
#elif __ARM__ || __ARMEL__ || __ARMEB__
|
||||
# define B_MAX_CPU_COUNT 1
|
||||
#elif __MIPSEL__
|
||||
# define B_MAX_CPU_COUNT 1
|
||||
#else
|
||||
# warning Unknown cpu
|
||||
# define B_MAX_CPU_COUNT 1
|
||||
#endif
|
||||
typedef struct {
|
||||
bigtime_t active_time; /* usec of doing useful work since boot */
|
||||
bool enabled;
|
||||
} cpu_info;
|
||||
|
||||
typedef enum cpu_types {
|
||||
/* TODO: add latest models */
|
||||
typedef struct {
|
||||
bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */
|
||||
|
||||
/* Motorola/IBM */
|
||||
B_CPU_PPC_UNKNOWN = 0,
|
||||
B_CPU_PPC_601 = 1,
|
||||
B_CPU_PPC_602 = 7,
|
||||
B_CPU_PPC_603 = 2,
|
||||
B_CPU_PPC_603e = 3,
|
||||
B_CPU_PPC_603ev = 8,
|
||||
B_CPU_PPC_604 = 4,
|
||||
B_CPU_PPC_604e = 5,
|
||||
B_CPU_PPC_604ev = 9,
|
||||
B_CPU_PPC_620 = 10,
|
||||
B_CPU_PPC_750 = 6,
|
||||
B_CPU_PPC_686 = 13,
|
||||
B_CPU_PPC_860 = 25,
|
||||
B_CPU_PPC_7400 = 26,
|
||||
B_CPU_PPC_7410 = 27,
|
||||
B_CPU_PPC_7447A = 28,
|
||||
B_CPU_PPC_7448 = 29,
|
||||
B_CPU_PPC_7450 = 30,
|
||||
B_CPU_PPC_7455 = 31,
|
||||
B_CPU_PPC_7457 = 32,
|
||||
B_CPU_PPC_8240 = 33,
|
||||
B_CPU_PPC_8245 = 34,
|
||||
uint32 cpu_count; /* number of cpus */
|
||||
|
||||
B_CPU_PPC_IBM_401A1 = 35,
|
||||
B_CPU_PPC_IBM_401B2 = 36,
|
||||
B_CPU_PPC_IBM_401C2 = 37,
|
||||
B_CPU_PPC_IBM_401D2 = 38,
|
||||
B_CPU_PPC_IBM_401E2 = 39,
|
||||
B_CPU_PPC_IBM_401F2 = 40,
|
||||
B_CPU_PPC_IBM_401G2 = 41,
|
||||
B_CPU_PPC_IBM_403 = 42,
|
||||
B_CPU_PPC_IBM_405GP = 43,
|
||||
B_CPU_PPC_IBM_405L = 44,
|
||||
B_CPU_PPC_IBM_750FX = 45,
|
||||
B_CPU_PPC_IBM_POWER3 = 46,
|
||||
uint64 max_pages; /* total # of accessible pages */
|
||||
uint64 used_pages; /* # of accessible pages in use */
|
||||
uint64 cached_pages;
|
||||
uint64 block_cache_pages;
|
||||
uint64 ignored_pages; /* # of ignored/inaccessible pages */
|
||||
|
||||
/* Intel */
|
||||
uint64 needed_memory;
|
||||
uint64 free_memory;
|
||||
|
||||
/* Updated according to Intel(R) Processor Identification and
|
||||
* the CPUID instruction (Table 4)
|
||||
* AP-485 Intel - 24161832.pdf
|
||||
*/
|
||||
B_CPU_INTEL_x86 = 0x1000,
|
||||
B_CPU_INTEL_PENTIUM = 0x1051,
|
||||
B_CPU_INTEL_PENTIUM75,
|
||||
B_CPU_INTEL_PENTIUM_486_OVERDRIVE,
|
||||
B_CPU_INTEL_PENTIUM_MMX,
|
||||
B_CPU_INTEL_PENTIUM_MMX_MODEL_4 = B_CPU_INTEL_PENTIUM_MMX,
|
||||
B_CPU_INTEL_PENTIUM_MMX_MODEL_8 = 0x1058,
|
||||
B_CPU_INTEL_PENTIUM75_486_OVERDRIVE,
|
||||
B_CPU_INTEL_PENTIUM_PRO = 0x1061,
|
||||
B_CPU_INTEL_PENTIUM_II = 0x1063,
|
||||
B_CPU_INTEL_PENTIUM_II_MODEL_3 = 0x1063,
|
||||
B_CPU_INTEL_PENTIUM_II_MODEL_5 = 0x1065,
|
||||
B_CPU_INTEL_CELERON = 0x1066,
|
||||
B_CPU_INTEL_CELERON_MODEL_22 = 0x11066,
|
||||
B_CPU_INTEL_PENTIUM_III = 0x1067,
|
||||
B_CPU_INTEL_PENTIUM_III_MODEL_8 = 0x1068,
|
||||
B_CPU_INTEL_PENTIUM_M = 0x1069,
|
||||
B_CPU_INTEL_PENTIUM_III_XEON = 0x106a,
|
||||
B_CPU_INTEL_PENTIUM_III_MODEL_11 = 0x106b,
|
||||
B_CPU_INTEL_ATOM = 0x1106c,
|
||||
B_CPU_INTEL_PENTIUM_M_MODEL_13 = 0x106d, /* Dothan */
|
||||
B_CPU_INTEL_PENTIUM_CORE,
|
||||
B_CPU_INTEL_PENTIUM_CORE_2,
|
||||
B_CPU_INTEL_PENTIUM_CORE_2_45_NM = 0x11067, /* Core 2 on 45 nm
|
||||
(Core 2 Extreme,
|
||||
Xeon model 23 or
|
||||
Core 2 Duo/Quad) */
|
||||
B_CPU_INTEL_PENTIUM_CORE_I5_M430 = 0x21065, /* Core i5 M 430 @ 2.27 */
|
||||
B_CPU_INTEL_PENTIUM_CORE_I7 = 0x1106a, /* Core i7 920 @ 2.6(6) */
|
||||
B_CPU_INTEL_PENTIUM_CORE_I7_Q720 = 0x1106e, /* Core i7 Q720 @ 1.6 */
|
||||
B_CPU_INTEL_PENTIUM_IV = 0x10f0,
|
||||
B_CPU_INTEL_PENTIUM_IV_MODEL_1,
|
||||
B_CPU_INTEL_PENTIUM_IV_MODEL_2,
|
||||
B_CPU_INTEL_PENTIUM_IV_MODEL_3,
|
||||
B_CPU_INTEL_PENTIUM_IV_MODEL_4,
|
||||
uint64 max_swap_pages;
|
||||
uint64 free_swap_pages;
|
||||
|
||||
/* AMD */
|
||||
uint32 page_faults; /* # of page faults */
|
||||
|
||||
// AMD Processor Recognition Application Note
|
||||
B_CPU_AMD_x86 = 0x1100,
|
||||
uint32 max_sems;
|
||||
uint32 used_sems;
|
||||
|
||||
// Family 5h
|
||||
B_CPU_AMD_K5_MODEL_0 = 0x1150,
|
||||
B_CPU_AMD_K5_MODEL_1 = 0x1151,
|
||||
B_CPU_AMD_K5_MODEL_2 = 0x1152,
|
||||
B_CPU_AMD_K5_MODEL_3 = 0x1153,
|
||||
B_CPU_AMD_K6_MODEL_6 = 0x1156,
|
||||
B_CPU_AMD_K6_MODEL_7 = 0x1157,
|
||||
B_CPU_AMD_K6_MODEL_8 = 0x1158,
|
||||
B_CPU_AMD_K6_2 = 0x1158,
|
||||
B_CPU_AMD_K6_MODEL_9 = 0x1159,
|
||||
B_CPU_AMD_K6_III = 0x1159,
|
||||
B_CPU_AMD_K6_III_MODEL_13 = 0x115d,
|
||||
uint32 max_ports;
|
||||
uint32 used_ports;
|
||||
|
||||
B_CPU_AMD_GEODE_LX = 0x115a,
|
||||
uint32 max_threads;
|
||||
uint32 used_threads;
|
||||
|
||||
// Family 6h
|
||||
B_CPU_AMD_ATHLON_MODEL_1 = 0x1161,
|
||||
B_CPU_AMD_ATHLON_MODEL_2 = 0x1162,
|
||||
uint32 max_teams;
|
||||
uint32 used_teams;
|
||||
|
||||
B_CPU_AMD_DURON = 0x1163,
|
||||
char kernel_name[B_FILE_NAME_LENGTH];
|
||||
char kernel_build_date[B_OS_NAME_LENGTH];
|
||||
char kernel_build_time[B_OS_NAME_LENGTH];
|
||||
|
||||
B_CPU_AMD_ATHLON_THUNDERBIRD = 0x1164,
|
||||
B_CPU_AMD_ATHLON_XP_MODEL_6 = 0x1166,
|
||||
B_CPU_AMD_ATHLON_XP_MODEL_7 = 0x1167,
|
||||
B_CPU_AMD_ATHLON_XP_MODEL_8 = 0x1168,
|
||||
B_CPU_AMD_ATHLON_XP_MODEL_10 = 0x116a, /* Barton */
|
||||
int64 kernel_version;
|
||||
uint32 abi; /* the system API */
|
||||
} system_info;
|
||||
|
||||
// Family fh
|
||||
B_CPU_AMD_ATHLON_64_MODEL_3 = 0x11f3,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_4 = 0x11f4,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_7 = 0x11f7,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_8 = 0x11f8,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_11 = 0x11fb,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_12 = 0x11fc,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_14 = 0x11fe,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_15 = 0x11ff,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_20 = 0x111f4,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_23 = 0x111f7,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_24 = 0x111f8,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_27 = 0x111fb,
|
||||
enum topology_level_type {
|
||||
B_TOPOLOGY_UNKNOWN,
|
||||
B_TOPOLOGY_ROOT,
|
||||
B_TOPOLOGY_SMT,
|
||||
B_TOPOLOGY_CORE,
|
||||
B_TOPOLOGY_PACKAGE
|
||||
};
|
||||
|
||||
// Athlon 64's below here could be really
|
||||
// Sempron 64's... however i've yet to find
|
||||
// proof online
|
||||
B_CPU_AMD_ATHLON_64_MODEL_31 = 0x111ff,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_35 = 0x211f3,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_43 = 0x211fb,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_47 = 0x211ff,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_63 = 0x311ff,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_79 = 0x411ff,
|
||||
B_CPU_AMD_ATHLON_64_MODEL_95 = 0x511ff,
|
||||
|
||||
B_CPU_AMD_SEMPRON_64_MODEL_28 = 0x111fc,
|
||||
B_CPU_AMD_SEMPRON_64_MODEL_44 = 0x211fc,
|
||||
B_CPU_AMD_SEMPRON_64_MODEL_127 = 0x711ff,
|
||||
|
||||
B_CPU_AMD_OPTERON_MODEL_5 = 0x11f5,
|
||||
B_CPU_AMD_OPTERON_MODEL_21 = 0x111f5,
|
||||
B_CPU_AMD_OPTERON_MODEL_33 = 0x211f1,
|
||||
B_CPU_AMD_OPTERON_MODEL_37 = 0x211f5,
|
||||
B_CPU_AMD_OPTERON_MODEL_39 = 0x211f7,
|
||||
|
||||
B_CPU_AMD_TURION_64_MODEL_36 = 0x211f4,
|
||||
B_CPU_AMD_TURION_64_MODEL_76 = 0x411fc,
|
||||
B_CPU_AMD_TURION_64_MODEL_104 = 0x611f8,
|
||||
|
||||
// Family 10h
|
||||
B_CPU_AMD_PHENOM_MODEL_2 = 0x1011f2,
|
||||
B_CPU_AMD_PHENOM_II_MODEL_4 = 0x1011f4,
|
||||
B_CPU_AMD_PHENOM_II_MODEL_5 = 0x1011f5,
|
||||
B_CPU_AMD_PHENOM_II_MODEL_6 = 0x1011f6,
|
||||
B_CPU_AMD_PHENOM_II_MODEL_10 = 0x1011fa,
|
||||
|
||||
// Family 12h
|
||||
B_CPU_AMD_A_SERIES_MODEL_1 = 0x3011f1,
|
||||
B_CPU_AMD_A_SERIES_MODEL_16 = 0x6111f0,
|
||||
B_CPU_AMD_A_SERIES_MODEL_19 = 0x6111f3,
|
||||
|
||||
// Family 14h
|
||||
B_CPU_AMD_C_SERIES = 0x5011f1,
|
||||
B_CPU_AMD_E_SERIES = 0x5011f2,
|
||||
|
||||
// Family 15h
|
||||
B_CPU_AMD_FX_SERIES_MODEL_1 = 0x6011f1, /* Bulldozer */
|
||||
B_CPU_AMD_FX_SERIES_MODEL_2 = 0x6011f2,
|
||||
|
||||
/* VIA/Cyrix */
|
||||
B_CPU_CYRIX_x86 = 0x1200,
|
||||
B_CPU_VIA_CYRIX_x86 = 0x1200,
|
||||
B_CPU_CYRIX_GXm = 0x1254,
|
||||
B_CPU_CYRIX_6x86MX = 0x1260,
|
||||
|
||||
/* VIA/IDT */
|
||||
B_CPU_IDT_x86 = 0x1300,
|
||||
B_CPU_VIA_IDT_x86 = 0x1300,
|
||||
B_CPU_IDT_WINCHIP_C6 = 0x1354,
|
||||
B_CPU_IDT_WINCHIP_2 = 0x1358,
|
||||
B_CPU_IDT_WINCHIP_3,
|
||||
B_CPU_VIA_C3_SAMUEL = 0x1366,
|
||||
B_CPU_VIA_C3_SAMUEL_2 = 0x1367,
|
||||
B_CPU_VIA_C3_EZRA_T = 0x1368,
|
||||
B_CPU_VIA_C3_NEHEMIAH = 0x1369,
|
||||
B_CPU_VIA_C7_ESTHER = 0x136a,
|
||||
B_CPU_VIA_C7_ESTHER_2 = 0x136d,
|
||||
B_CPU_VIA_NANO_ISAIAH = 0x136f,
|
||||
|
||||
/* Transmeta */
|
||||
B_CPU_TRANSMETA_x86 = 0x1600,
|
||||
B_CPU_TRANSMETA_CRUSOE = 0x1654,
|
||||
B_CPU_TRANSMETA_EFFICEON = 0x16f2,
|
||||
B_CPU_TRANSMETA_EFFICEON_2 = 0x16f3,
|
||||
|
||||
/* Rise */
|
||||
B_CPU_RISE_x86 = 0x1400,
|
||||
B_CPU_RISE_mP6 = 0x1450,
|
||||
|
||||
/* National Semiconductor */
|
||||
B_CPU_NATIONAL_x86 = 0x1500,
|
||||
B_CPU_NATIONAL_GEODE_GX1 = 0x1554,
|
||||
B_CPU_NATIONAL_GEODE_GX2,
|
||||
|
||||
/* For compatibility */
|
||||
B_CPU_AMD_29K = 14,
|
||||
enum cpu_platform {
|
||||
B_CPU_UNKNOWN,
|
||||
B_CPU_x86,
|
||||
B_CPU_MC6502,
|
||||
B_CPU_Z80,
|
||||
B_CPU_ALPHA,
|
||||
B_CPU_MIPS,
|
||||
B_CPU_HPPA,
|
||||
B_CPU_M68K,
|
||||
B_CPU_ARM,
|
||||
B_CPU_SH,
|
||||
B_CPU_SPARC
|
||||
} cpu_type;
|
||||
B_CPU_x86_64
|
||||
};
|
||||
|
||||
enum cpu_vendor {
|
||||
B_CPU_VENDOR_UNKNOWN,
|
||||
B_CPU_VENDOR_AMD,
|
||||
B_CPU_VENDOR_CYRIX,
|
||||
B_CPU_VENDOR_IDT,
|
||||
B_CPU_VENDOR_INTEL,
|
||||
B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR,
|
||||
B_CPU_VENDOR_RISE,
|
||||
B_CPU_VENDOR_TRANSMETA,
|
||||
B_CPU_VENDOR_VIA
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
enum cpu_platform platform;
|
||||
} cpu_topology_root_info;
|
||||
|
||||
typedef struct {
|
||||
enum cpu_vendor vendor;
|
||||
uint32 cache_line_size;
|
||||
} cpu_topology_package_info;
|
||||
|
||||
typedef struct {
|
||||
uint32 model;
|
||||
uint64 default_frequency;
|
||||
} cpu_topology_core_info;
|
||||
|
||||
typedef struct {
|
||||
uint32 id;
|
||||
enum topology_level_type type;
|
||||
uint32 level;
|
||||
|
||||
union {
|
||||
cpu_topology_root_info root;
|
||||
cpu_topology_package_info package;
|
||||
cpu_topology_core_info core;
|
||||
} data;
|
||||
} cpu_topology_node_info;
|
||||
|
||||
|
||||
extern status_t get_system_info(system_info* info);
|
||||
extern status_t get_cpu_info(uint32 firstCPU, uint32 cpuCount,
|
||||
cpu_info* info);
|
||||
extern status_t get_cpu_topology_info(cpu_topology_node_info* topologyInfos,
|
||||
uint32* topologyInfoCount);
|
||||
|
||||
#define B_CPU_x86_VENDOR_MASK 0xff00
|
||||
|
||||
@ -713,76 +577,6 @@ extern status_t get_cpuid(cpuid_info *info, uint32 eaxRegister,
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum platform_types {
|
||||
B_BEBOX_PLATFORM = 0,
|
||||
B_MAC_PLATFORM,
|
||||
B_AT_CLONE_PLATFORM,
|
||||
B_ENIAC_PLATFORM,
|
||||
B_APPLE_II_PLATFORM,
|
||||
B_CRAY_PLATFORM,
|
||||
B_LISA_PLATFORM,
|
||||
B_TI_994A_PLATFORM,
|
||||
B_TIMEX_SINCLAIR_PLATFORM,
|
||||
B_ORAC_1_PLATFORM,
|
||||
B_HAL_PLATFORM,
|
||||
B_BESM_6_PLATFORM,
|
||||
B_MK_61_PLATFORM,
|
||||
B_NINTENDO_64_PLATFORM,
|
||||
B_AMIGA_PLATFORM,
|
||||
B_ATARI_PLATFORM,
|
||||
B_64_BIT_PC_PLATFORM
|
||||
} platform_type;
|
||||
|
||||
typedef struct {
|
||||
bigtime_t active_time; /* usec of doing useful work since boot */
|
||||
} cpu_info;
|
||||
|
||||
|
||||
typedef int32 machine_id[2]; /* unique machine ID */
|
||||
|
||||
typedef struct {
|
||||
machine_id id; /* unique machine ID */
|
||||
bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */
|
||||
|
||||
int32 cpu_count; /* number of cpus */
|
||||
enum cpu_types cpu_type; /* type of cpu */
|
||||
int32 cpu_revision; /* revision # of cpu */
|
||||
cpu_info cpu_infos[B_MAX_CPU_COUNT]; /* info about individual cpus */
|
||||
int64 cpu_clock_speed; /* processor clock speed (Hz) */
|
||||
int64 bus_clock_speed; /* bus clock speed (Hz) */
|
||||
enum platform_types platform_type; /* type of machine we're on */
|
||||
|
||||
int32 max_pages; /* total # of accessible pages */
|
||||
int32 used_pages; /* # of accessible pages in use */
|
||||
int32 page_faults; /* # of page faults */
|
||||
int32 max_sems;
|
||||
int32 used_sems;
|
||||
int32 max_ports;
|
||||
int32 used_ports;
|
||||
int32 max_threads;
|
||||
int32 used_threads;
|
||||
int32 max_teams;
|
||||
int32 used_teams;
|
||||
|
||||
char kernel_name[B_FILE_NAME_LENGTH];
|
||||
char kernel_build_date[B_OS_NAME_LENGTH];
|
||||
char kernel_build_time[B_OS_NAME_LENGTH];
|
||||
int64 kernel_version;
|
||||
|
||||
bigtime_t _busy_wait_time; /* reserved for whatever */
|
||||
|
||||
int32 cached_pages;
|
||||
uint32 abi; /* the system API */
|
||||
int32 ignored_pages; /* # of ignored/inaccessible pages */
|
||||
int32 pad;
|
||||
} system_info;
|
||||
|
||||
/* system private, use macro instead */
|
||||
extern status_t _get_system_info(system_info *info, size_t size);
|
||||
|
||||
#define get_system_info(info) \
|
||||
_get_system_info((info), sizeof(*(info)))
|
||||
|
||||
extern int32 is_computer_on(void);
|
||||
extern double is_computer_on_fire(void);
|
||||
|
||||
|
@ -49,6 +49,11 @@ enum be_task_flags {
|
||||
B_MIDI_PROCESSING = 0x800
|
||||
};
|
||||
|
||||
enum scheduler_mode {
|
||||
SCHEDULER_MODE_LOW_LATENCY,
|
||||
SCHEDULER_MODE_POWER_SAVING,
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
||||
@ -58,6 +63,9 @@ int32 suggest_thread_priority(uint32 task_flags = B_DEFAULT_MEDIA_PRIORITY,
|
||||
bigtime_t estimate_max_scheduling_latency(thread_id th = -1);
|
||||
/* default is current thread */
|
||||
|
||||
status_t set_scheduler_mode(int32 mode);
|
||||
int32 get_scheduler_mode(void);
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
@ -67,6 +75,9 @@ int32 suggest_thread_priority(uint32 what, int32 period, bigtime_t jitter,
|
||||
bigtime_t estimate_max_scheduling_latency(thread_id th);
|
||||
/* default is current thread */
|
||||
|
||||
status_t set_scheduler_mode(int32 mode);
|
||||
int32 get_scheduler_mode(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SCHEDULER_H
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
private:
|
||||
bool fStarted;
|
||||
area_id fArea;
|
||||
volatile BPrivate::media::TimeSourceTransmit* fBuf;
|
||||
BPrivate::media::TimeSourceTransmit* fBuf;
|
||||
BPrivate::media::SlaveNodes* fSlaveNodes;
|
||||
|
||||
area_id _reserved_area;
|
||||
|
@ -396,8 +396,8 @@ private:
|
||||
int32 withLength);
|
||||
|
||||
private:
|
||||
vint32& _ReferenceCount();
|
||||
const vint32& _ReferenceCount() const;
|
||||
int32& _ReferenceCount();
|
||||
const int32& _ReferenceCount() const;
|
||||
bool _IsShareable() const;
|
||||
void _FreePrivateData();
|
||||
|
||||
|
@ -196,19 +196,21 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Atomic functions; previous value is returned */
|
||||
extern int32 atomic_set(vint32 *value, int32 newValue);
|
||||
extern int32 atomic_test_and_set(vint32 *value, int32 newValue, int32 testAgainst);
|
||||
extern int32 atomic_add(vint32 *value, int32 addValue);
|
||||
extern int32 atomic_and(vint32 *value, int32 andValue);
|
||||
extern int32 atomic_or(vint32 *value, int32 orValue);
|
||||
extern int32 atomic_get(vint32 *value);
|
||||
extern void atomic_set(int32* value, int32 newValue);
|
||||
extern int32 atomic_get_and_set(int32* value, int32 newValue);
|
||||
extern int32 atomic_test_and_set(int32 *value, int32 newValue, int32 testAgainst);
|
||||
extern int32 atomic_add(int32 *value, int32 addValue);
|
||||
extern int32 atomic_and(int32 *value, int32 andValue);
|
||||
extern int32 atomic_or(int32 *value, int32 orValue);
|
||||
extern int32 atomic_get(int32 *value);
|
||||
|
||||
extern int64 atomic_set64(vint64 *value, int64 newValue);
|
||||
extern int64 atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst);
|
||||
extern int64 atomic_add64(vint64 *value, int64 addValue);
|
||||
extern int64 atomic_and64(vint64 *value, int64 andValue);
|
||||
extern int64 atomic_or64(vint64 *value, int64 orValue);
|
||||
extern int64 atomic_get64(vint64 *value);
|
||||
extern void atomic_set64(int64* value, int64 newValue);
|
||||
extern int64 atomic_get_and_set64(int64* value, int64 newValue);
|
||||
extern int64 atomic_test_and_set64(int64 *value, int64 newValue, int64 testAgainst);
|
||||
extern int64 atomic_add64(int64 *value, int64 addValue);
|
||||
extern int64 atomic_and64(int64 *value, int64 andValue);
|
||||
extern int64 atomic_or64(int64 *value, int64 orValue);
|
||||
extern int64 atomic_get64(int64 *value);
|
||||
|
||||
/* Other stuff */
|
||||
extern void* get_stack_frame(void);
|
||||
@ -240,15 +242,6 @@ extern void* get_stack_frame(void);
|
||||
__sync_fetch_and_and(valuePointer, andValue)
|
||||
#define atomic_or(valuePointer, orValue) \
|
||||
__sync_fetch_and_or(valuePointer, orValue)
|
||||
#define atomic_get(valuePointer) \
|
||||
__sync_fetch_and_or(valuePointer, 0)
|
||||
// No equivalent to atomic_get(). We simulate it via atomic or. On most
|
||||
// (all?) 32+ bit architectures aligned 32 bit reads will be atomic anyway,
|
||||
// though.
|
||||
|
||||
// Note: No equivalent for atomic_set(). It could be simulated by a
|
||||
// get + atomic test and set loop, but calling the atomic_set() implementation
|
||||
// might be faster.
|
||||
|
||||
#endif // B_USE_BUILTIN_ATOMIC_FUNCTIONS && __GNUC__ >= 4
|
||||
|
||||
|
@ -104,10 +104,8 @@
|
||||
/* TODO: check */
|
||||
#define _SC_IOV_MAX 32
|
||||
#define _SC_UIO_MAXIOV _SC_IOV_MAX
|
||||
#define _SC_NPROCESSORS_MAX 33
|
||||
#define _SC_NPROCESSORS_CONF 34
|
||||
#define _SC_NPROCESSORS_ONLN 35
|
||||
#define _SC_CPUID_MAX 36
|
||||
#define _SC_ATEXIT_MAX 37
|
||||
#define _SC_PASS_MAX 39
|
||||
#define _SC_PHYS_PAGES 40
|
||||
|
@ -14,19 +14,6 @@ enum {
|
||||
// ioctl response with kMagicFreqID
|
||||
IDENTIFY_DEVICE = B_DEVICE_OP_CODES_END + 20001,
|
||||
|
||||
// CPU Frequence:
|
||||
// get a list of freq_info, the list is terminated with a element with
|
||||
// frequency = 0
|
||||
GET_CPU_FREQ_STATES = B_DEVICE_OP_CODES_END + 20005,
|
||||
// get and set a freq_info
|
||||
GET_CURENT_CPU_FREQ_STATE,
|
||||
SET_CPU_FREQ_STATE,
|
||||
// start watching for frequency changes, ioctl blocks until the frequency
|
||||
// has changed
|
||||
WATCH_CPU_FREQ,
|
||||
// stop all watching ioctl, ioctl return B_ERROR
|
||||
STOP_WATCHING_CPU_FREQ,
|
||||
|
||||
GET_BATTERY_INFO,
|
||||
GET_EXTENDED_BATTERY_INFO,
|
||||
WATCH_BATTERY,
|
||||
@ -34,22 +21,6 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
// CPU Frequence:
|
||||
// magic id returned by IDENTIFY_DEVICE
|
||||
const uint32 kMagicFreqID = 48921;
|
||||
|
||||
|
||||
#define MAX_CPU_FREQUENCY_STATES 10
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16 frequency; // [Mhz]
|
||||
uint16 volts;
|
||||
uint16 id;
|
||||
int power;
|
||||
} freq_info;
|
||||
|
||||
|
||||
// ACPI Battery:
|
||||
// magic id returned by IDENTIFY_DEVICE
|
||||
const uint32 kMagicACPIBatteryID = 17822;
|
||||
|
@ -30,7 +30,7 @@
|
||||
typedef uint32_t bus_addr_t;
|
||||
typedef uint32_t bus_size_t;
|
||||
|
||||
#define atomic_readandclear_int(ptr) atomic_set((int32 *)(ptr), 0)
|
||||
#define atomic_readandclear_int(ptr) atomic_get_and_set((int32*)(ptr), 0)
|
||||
#define atomic_set_int(ptr, value) atomic_or((int32 *)(ptr), value)
|
||||
|
||||
#define mtx_lock mutex_lock
|
||||
|
@ -50,6 +50,7 @@
|
||||
// #pragma mark - fssh_atomic.h
|
||||
|
||||
#define atomic_set fssh_atomic_set
|
||||
#define atomic_get_and_Set fssh_atomic_get_and_set
|
||||
#define atomic_test_and_set fssh_atomic_test_and_set
|
||||
#define atomic_add fssh_atomic_add
|
||||
#define atomic_and fssh_atomic_and
|
||||
|
@ -15,21 +15,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int32_t fssh_atomic_set(vint32_t *value, int32_t newValue);
|
||||
int32_t fssh_atomic_test_and_set(vint32_t *value, int32_t newValue,
|
||||
void fssh_atomic_set(int32_t* value, int32_t newValue);
|
||||
int32_t fssh_atomic_get_and_set(int32_t* value, int32_t newValue);
|
||||
int32_t fssh_atomic_test_and_set(int32_t *value, int32_t newValue,
|
||||
int32_t testAgainst);
|
||||
int32_t fssh_atomic_add(vint32_t *value, int32_t addValue);
|
||||
int32_t fssh_atomic_and(vint32_t *value, int32_t andValue);
|
||||
int32_t fssh_atomic_or(vint32_t *value, int32_t orValue);
|
||||
int32_t fssh_atomic_get(vint32_t *value);
|
||||
int32_t fssh_atomic_add(int32_t *value, int32_t addValue);
|
||||
int32_t fssh_atomic_and(int32_t *value, int32_t andValue);
|
||||
int32_t fssh_atomic_or(int32_t *value, int32_t orValue);
|
||||
int32_t fssh_atomic_get(int32_t *value);
|
||||
|
||||
int64_t fssh_atomic_set64(vint64_t *value, int64_t newValue);
|
||||
int64_t fssh_atomic_test_and_set64(vint64_t *value, int64_t newValue,
|
||||
void fssh_atomic_set64(int64_t* value, int64_t newValue);
|
||||
int64_t fssh_atomic_get_and_set64(int64_t* value, int64_t newValue);
|
||||
int64_t fssh_atomic_test_and_set64(int64_t *value, int64_t newValue,
|
||||
int64_t testAgainst);
|
||||
int64_t fssh_atomic_add64(vint64_t *value, int64_t addValue);
|
||||
int64_t fssh_atomic_and64(vint64_t *value, int64_t andValue);
|
||||
int64_t fssh_atomic_or64(vint64_t *value, int64_t orValue);
|
||||
int64_t fssh_atomic_get64(vint64_t *value);
|
||||
int64_t fssh_atomic_add64(int64_t *value, int64_t addValue);
|
||||
int64_t fssh_atomic_and64(int64_t *value, int64_t andValue);
|
||||
int64_t fssh_atomic_or64(int64_t *value, int64_t orValue);
|
||||
int64_t fssh_atomic_get64(int64_t *value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
typedef struct lock {
|
||||
sem_id sem;
|
||||
vint32 count;
|
||||
int32 count;
|
||||
} lock;
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
typedef struct lock {
|
||||
sem_id sem;
|
||||
vint32 count;
|
||||
int32 count;
|
||||
} lock;
|
||||
|
||||
|
||||
@ -82,4 +82,4 @@ class Autolock {
|
||||
};
|
||||
|
||||
|
||||
#endif /* LOCK_H */
|
||||
#endif /* LOCK_H */
|
||||
|
@ -62,10 +62,8 @@ public:
|
||||
uint32 reservedSlots);
|
||||
void Close(bool cancelPending);
|
||||
|
||||
status_t Add(DPCCallback* callback,
|
||||
bool schedulerLocked);
|
||||
status_t Add(void (*function)(void*), void* argument,
|
||||
bool schedulerLocked);
|
||||
status_t Add(DPCCallback* callback);
|
||||
status_t Add(void (*function)(void*), void* argument);
|
||||
bool Cancel(DPCCallback* callback);
|
||||
|
||||
thread_id Thread() const
|
||||
|
@ -17,7 +17,7 @@ enum {
|
||||
};
|
||||
|
||||
struct messaging_area_header {
|
||||
vint32 lock_counter;
|
||||
int32 lock_counter;
|
||||
int32 size; // set to 0, when area is discarded
|
||||
area_id kernel_area;
|
||||
area_id next_kernel_area;
|
||||
|
@ -92,7 +92,7 @@ private:
|
||||
private:
|
||||
ThreadCreationAttributes fCreationAttributes;
|
||||
char fThreadName[B_OS_NAME_LENGTH];
|
||||
bool fPendingDPC;
|
||||
int32 fPendingDPC;
|
||||
};
|
||||
|
||||
|
||||
|
@ -54,6 +54,8 @@ protected:
|
||||
inline void UpdatePeriodicStartTime();
|
||||
inline void CheckPeriodicOverrun(bigtime_t now);
|
||||
|
||||
inline void CancelTimer();
|
||||
|
||||
protected:
|
||||
int32 fID;
|
||||
timer fTimer;
|
||||
@ -62,6 +64,7 @@ protected:
|
||||
bigtime_t fInterval;
|
||||
uint32 fOverrunCount;
|
||||
bool fScheduled; // fTimer scheduled
|
||||
int32 fSkip;
|
||||
};
|
||||
|
||||
|
||||
|
22
headers/private/kernel/arch/atomic.h
Normal file
22
headers/private/kernel/arch/atomic.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_ATOMIC_H
|
||||
#define _KERNEL_ARCH_ATOMIC_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
# include <arch/x86/64/atomic.h>
|
||||
#elif __INTEL__
|
||||
# include <arch/x86/32/atomic.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_ATOMIC_H
|
||||
|
@ -41,13 +41,8 @@ ssize_t arch_cpu_user_strlcpy(char *to, const char *from, size_t size,
|
||||
status_t arch_cpu_user_memset(void *s, char c, size_t count,
|
||||
addr_t *faultHandler);
|
||||
|
||||
void arch_cpu_idle(void);
|
||||
void arch_cpu_sync_icache(void *address, size_t length);
|
||||
|
||||
void arch_cpu_memory_read_barrier(void);
|
||||
void arch_cpu_memory_write_barrier(void);
|
||||
void arch_cpu_memory_read_write_barrier(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -55,4 +50,6 @@ void arch_cpu_memory_read_write_barrier(void);
|
||||
|
||||
#include <arch_cpu.h>
|
||||
|
||||
#define CACHE_LINE_ALIGN __attribute__((aligned(CACHE_LINE_SIZE)))
|
||||
|
||||
#endif /* _KERNEL_ARCH_CPU_H */
|
||||
|
@ -34,6 +34,7 @@ void arch_int_enable_io_interrupt(int irq);
|
||||
void arch_int_disable_io_interrupt(int irq);
|
||||
void arch_int_configure_io_interrupt(int irq, uint32 config);
|
||||
bool arch_int_are_interrupts_enabled(void);
|
||||
void arch_int_assign_to_cpu(int32 irq, int32 cpu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -8,23 +8,18 @@
|
||||
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
class CPUSet;
|
||||
|
||||
// must match MAX_BOOT_CPUS in platform_kernel_args.h
|
||||
#define SMP_MAX_CPUS MAX_BOOT_CPUS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
status_t arch_smp_init(kernel_args* args);
|
||||
status_t arch_smp_per_cpu_init(kernel_args* args, int32 cpu);
|
||||
|
||||
status_t arch_smp_init(struct kernel_args *args);
|
||||
status_t arch_smp_per_cpu_init(struct kernel_args *args, int32 cpu);
|
||||
void arch_smp_send_ici(int32 target_cpu);
|
||||
void arch_smp_send_broadcast_ici(void);
|
||||
void arch_smp_send_broadcast_ici();
|
||||
void arch_smp_send_multicast_ici(CPUSet& cpuSet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_ARCH_SMP_H */
|
||||
|
@ -18,7 +18,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
status_t arch_system_info_init(struct kernel_args *args);
|
||||
status_t arch_get_system_info(system_info *info, size_t size);
|
||||
void arch_fill_topology_node(cpu_topology_node_info* node, int32 cpu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
97
headers/private/kernel/arch/x86/32/atomic.h
Normal file
97
headers/private/kernel/arch/x86/32/atomic.h
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_X86_32_ATOMIC_H
|
||||
#define _KERNEL_ARCH_X86_32_ATOMIC_H
|
||||
|
||||
|
||||
static inline void
|
||||
memory_read_barrier_inline(void)
|
||||
{
|
||||
asm volatile("lock; addl $0, (%%esp)" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
memory_write_barrier_inline(void)
|
||||
{
|
||||
asm volatile("lock; addl $0, (%%esp)" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
memory_full_barrier_inline(void)
|
||||
{
|
||||
asm volatile("lock; addl $0, (%%esp)" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
#define memory_read_barrier memory_read_barrier_inline
|
||||
#define memory_write_barrier memory_write_barrier_inline
|
||||
#define memory_full_barrier memory_full_barrier_inline
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
memory_write_barrier();
|
||||
*(volatile int32*)value = newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_and_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("xchgl %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
|
||||
{
|
||||
asm volatile("lock; cmpxchgl %2, (%3)"
|
||||
: "=a" (newValue)
|
||||
: "0" (testAgainst), "r" (newValue), "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_add_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("lock; xaddl %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_inline(int32* value)
|
||||
{
|
||||
int32 newValue = *(volatile int32*)value;
|
||||
memory_read_barrier();
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
#define atomic_set atomic_set_inline
|
||||
#define atomic_get_and_set atomic_get_and_set_inline
|
||||
#ifndef atomic_test_and_set
|
||||
# define atomic_test_and_set atomic_test_and_set_inline
|
||||
#endif
|
||||
#ifndef atomic_add
|
||||
# define atomic_add atomic_add_inline
|
||||
#endif
|
||||
#define atomic_get atomic_get_inline
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_X86_32_ATOMIC_H
|
||||
|
@ -9,30 +9,42 @@
|
||||
#define _KERNEL_ARCH_X86_32_DESCRIPTORS_H
|
||||
|
||||
|
||||
#define KERNEL_CODE_SEG 0x8
|
||||
#define KERNEL_DATA_SEG 0x10
|
||||
// Segments common for all CPUs.
|
||||
#define KERNEL_CODE_SEGMENT 1
|
||||
#define KERNEL_DATA_SEGMENT 2
|
||||
|
||||
#define USER_CODE_SEG 0x1b
|
||||
#define USER_DATA_SEG 0x23
|
||||
#define USER_CODE_SEGMENT 3
|
||||
#define USER_DATA_SEGMENT 4
|
||||
|
||||
#define APM_CODE32_SEGMENT 0x28
|
||||
#define APM_CODE16_SEGMENT 0x30
|
||||
#define APM_DATA_SEGMENT 0x38
|
||||
#define APM_CODE32_SEGMENT 5
|
||||
#define APM_CODE16_SEGMENT 6
|
||||
#define APM_DATA_SEGMENT 7
|
||||
|
||||
#define BIOS_DATA_SEGMENT 0x40
|
||||
#define BIOS_DATA_SEGMENT 8
|
||||
|
||||
// Per-CPU segments.
|
||||
#define TSS_SEGMENT 9
|
||||
#define DOUBLE_FAULT_TSS_SEGMENT 10
|
||||
#define KERNEL_TLS_SEGMENT 11
|
||||
#define USER_TLS_SEGMENT 12
|
||||
#define APM_SEGMENT 13
|
||||
|
||||
#define GDT_SEGMENT_COUNT 14
|
||||
|
||||
|
||||
#define KERNEL_CODE_SELECTOR ((KERNEL_CODE_SEGMENT << 3) | DPL_KERNEL)
|
||||
#define KERNEL_DATA_SELECTOR ((KERNEL_DATA_SEGMENT << 3) | DPL_KERNEL)
|
||||
|
||||
#define USER_CODE_SELECTOR ((USER_CODE_SEGMENT << 3) | DPL_USER)
|
||||
#define USER_DATA_SELECTOR ((USER_DATA_SEGMENT << 3) | DPL_USER)
|
||||
|
||||
#define KERNEL_TLS_SELECTOR ((KERNEL_TLS_SEGMENT << 3) | DPL_KERNEL)
|
||||
|
||||
|
||||
#ifndef _ASSEMBLER
|
||||
// this file can also be included from assembler as well
|
||||
// (and is in arch_interrupts.S)
|
||||
|
||||
#define DOUBLE_FAULT_TSS_BASE_SEGMENT 9
|
||||
#define TSS_BASE_SEGMENT (DOUBLE_FAULT_TSS_BASE_SEGMENT + smp_get_num_cpus())
|
||||
#define TLS_BASE_SEGMENT (TSS_BASE_SEGMENT + smp_get_num_cpus())
|
||||
#define APM_BASE_SEGMENT (TLS_BASE_SEGMENT + smp_get_num_cpus())
|
||||
|
||||
#define TSS_SEGMENT(cpu) (TSS_BASE_SEGMENT + cpu)
|
||||
|
||||
// defines entries in the GDT/LDT
|
||||
|
||||
struct segment_descriptor {
|
||||
@ -73,6 +85,9 @@ struct tss {
|
||||
uint16 io_map_base;
|
||||
};
|
||||
|
||||
typedef segment_descriptor global_descriptor_table[GDT_SEGMENT_COUNT];
|
||||
extern global_descriptor_table gGDTs[];
|
||||
|
||||
|
||||
static inline void
|
||||
clear_segment_descriptor(segment_descriptor* desc)
|
||||
@ -141,6 +156,13 @@ set_tss_descriptor(segment_descriptor* desc, addr_t base, uint32 limit)
|
||||
}
|
||||
|
||||
|
||||
static inline segment_descriptor*
|
||||
get_gdt(int32 cpu)
|
||||
{
|
||||
return gGDTs[cpu];
|
||||
}
|
||||
|
||||
|
||||
#endif /* _ASSEMBLER */
|
||||
|
||||
#endif /* _KERNEL_ARCH_X86_32_DESCRIPTORS_H */
|
||||
|
@ -37,7 +37,7 @@ struct iframe {
|
||||
uint32 user_ss;
|
||||
};
|
||||
|
||||
#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SEG \
|
||||
#define IFRAME_IS_USER(f) ((f)->cs == USER_CODE_SELECTOR \
|
||||
|| ((f)->flags & 0x20000) != 0)
|
||||
|
||||
|
||||
|
153
headers/private/kernel/arch/x86/64/atomic.h
Normal file
153
headers/private/kernel/arch/x86/64/atomic.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2014, Paweł Dziepak, pdziepak@quarnos.org.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_ARCH_X86_64_ATOMIC_H
|
||||
#define _KERNEL_ARCH_X86_64_ATOMIC_H
|
||||
|
||||
|
||||
static inline void
|
||||
memory_read_barrier_inline(void)
|
||||
{
|
||||
asm volatile("lfence" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
memory_write_barrier_inline(void)
|
||||
{
|
||||
asm volatile("sfence" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
memory_full_barrier_inline(void)
|
||||
{
|
||||
asm volatile("mfence" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
#define memory_read_barrier memory_read_barrier_inline
|
||||
#define memory_write_barrier memory_write_barrier_inline
|
||||
#define memory_full_barrier memory_full_barrier_inline
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
memory_write_barrier();
|
||||
*(volatile int32*)value = newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_and_set_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("xchg %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_test_and_set_inline(int32* value, int32 newValue, int32 testAgainst)
|
||||
{
|
||||
asm volatile("lock; cmpxchgl %2, (%3)"
|
||||
: "=a" (newValue)
|
||||
: "0" (testAgainst), "r" (newValue), "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_add_inline(int32* value, int32 newValue)
|
||||
{
|
||||
asm volatile("lock; xaddl %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int32
|
||||
atomic_get_inline(int32* value)
|
||||
{
|
||||
int32 newValue = *(volatile int32*)value;
|
||||
memory_read_barrier();
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
atomic_set64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
memory_write_barrier();
|
||||
*(volatile int64*)value = newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_get_and_set64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
asm volatile("xchgq %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_test_and_set64_inline(int64* value, int64 newValue, int64 testAgainst)
|
||||
{
|
||||
asm volatile("lock; cmpxchgq %2, (%3)"
|
||||
: "=a" (newValue)
|
||||
: "0" (testAgainst), "r" (newValue), "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_add64_inline(int64* value, int64 newValue)
|
||||
{
|
||||
asm volatile("lock; xaddq %0, (%1)"
|
||||
: "+r" (newValue)
|
||||
: "r" (value)
|
||||
: "memory");
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
static inline int64
|
||||
atomic_get64_inline(int64* value)
|
||||
{
|
||||
int64 newValue = *(volatile int64*)value;
|
||||
memory_read_barrier();
|
||||
return newValue;
|
||||
}
|
||||
|
||||
|
||||
#define atomic_set atomic_set_inline
|
||||
#define atomic_get_and_set atomic_get_and_set_inline
|
||||
#ifndef atomic_test_and_set
|
||||
# define atomic_test_and_set atomic_test_and_set_inline
|
||||
#endif
|
||||
#ifndef atomic_add
|
||||
# define atomic_add atomic_add_inline
|
||||
#endif
|
||||
#define atomic_get atomic_get_inline
|
||||
|
||||
#define atomic_set64 atomic_set64_inline
|
||||
#define atomic_get_and_set64 atomic_get_and_set64_inline
|
||||
#define atomic_test_and_set64 atomic_test_and_set64_inline
|
||||
#define atomic_add64 atomic_add64_inline
|
||||
#define atomic_get64 atomic_get64_inline
|
||||
|
||||
|
||||
#endif // _KERNEL_ARCH_X86_64_ATOMIC_H
|
||||
|
@ -8,19 +8,28 @@
|
||||
|
||||
// Segment definitions.
|
||||
// Note that the ordering of these is important to SYSCALL/SYSRET.
|
||||
#define KERNEL_CODE_SEG 0x08
|
||||
#define KERNEL_DATA_SEG 0x10
|
||||
#define USER_DATA_SEG 0x1b
|
||||
#define USER_CODE_SEG 0x23
|
||||
#define KERNEL_CODE_SEGMENT 1
|
||||
#define KERNEL_DATA_SEGMENT 2
|
||||
#define USER_DATA_SEGMENT 3
|
||||
#define USER_CODE_SEGMENT 4
|
||||
|
||||
#define TSS_BASE_SEGMENT 5
|
||||
|
||||
#define TSS_SEGMENT(cpu) (TSS_BASE_SEGMENT + cpu * 2)
|
||||
|
||||
#define GDT_SEGMENT_COUNT (TSS_BASE_SEGMENT + SMP_MAX_CPUS * 2)
|
||||
|
||||
|
||||
#define KERNEL_CODE_SELECTOR ((KERNEL_CODE_SEGMENT << 3) | DPL_KERNEL)
|
||||
#define KERNEL_DATA_SELECTOR ((KERNEL_DATA_SEGMENT << 3) | DPL_KERNEL)
|
||||
|
||||
#define USER_CODE_SELECTOR ((USER_CODE_SEGMENT << 3) | DPL_USER)
|
||||
#define USER_DATA_SELECTOR ((USER_DATA_SEGMENT << 3) | DPL_USER)
|
||||
|
||||
|
||||
#ifndef _ASSEMBLER
|
||||
|
||||
|
||||
#define TSS_BASE_SEGMENT 5
|
||||
#define TSS_SEGMENT(cpu) (TSS_BASE_SEGMENT + cpu * 2)
|
||||
|
||||
|
||||
// Structure of a segment descriptor.
|
||||
struct segment_descriptor {
|
||||
uint32 limit0 : 16;
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define APIC_TRIGGER_MODE_LEVEL (1 << 15)
|
||||
|
||||
/* Interrupt Command defines */
|
||||
#define APIC_INTR_COMMAND_1_MASK 0xfff3f000
|
||||
#define APIC_INTR_COMMAND_1_MASK 0xfff32000
|
||||
#define APIC_INTR_COMMAND_2_MASK 0x00ffffff
|
||||
|
||||
#define APIC_INTR_COMMAND_1_DEST_MODE_PHYSICAL 0
|
||||
@ -110,6 +110,7 @@
|
||||
#if !_BOOT_MODE
|
||||
|
||||
bool apic_available();
|
||||
bool x2apic_available();
|
||||
uint32 apic_read(uint32 offset);
|
||||
void apic_write(uint32 offset, uint32 data);
|
||||
uint32 apic_local_id();
|
||||
@ -122,10 +123,9 @@ void apic_disable_local_ints();
|
||||
|
||||
uint32 apic_spurious_intr_vector();
|
||||
void apic_set_spurious_intr_vector(uint32 config);
|
||||
uint32 apic_intr_command_1();
|
||||
void apic_set_intr_command_1(uint32 config);
|
||||
uint32 apic_intr_command_2();
|
||||
void apic_set_intr_command_2(uint32 config);
|
||||
|
||||
void apic_set_interrupt_command(uint32 destination, uint32 mode);
|
||||
bool apic_interrupt_delivered(void);
|
||||
|
||||
uint32 apic_lvt_timer();
|
||||
void apic_set_lvt_timer(uint32 config);
|
||||
|
@ -24,14 +24,25 @@
|
||||
#endif // !_ASSEMBLER
|
||||
|
||||
|
||||
#define CPU_MAX_CACHE_LEVEL 8
|
||||
|
||||
#define CACHE_LINE_SIZE 64
|
||||
|
||||
|
||||
// MSR registers (possibly Intel specific)
|
||||
#define IA32_MSR_TSC 0x10
|
||||
#define IA32_MSR_APIC_BASE 0x1b
|
||||
|
||||
#define IA32_MSR_PLATFORM_INFO 0xce
|
||||
#define IA32_MSR_MPERF 0xe7
|
||||
#define IA32_MSR_APERF 0xe8
|
||||
#define IA32_MSR_MTRR_CAPABILITIES 0xfe
|
||||
#define IA32_MSR_SYSENTER_CS 0x174
|
||||
#define IA32_MSR_SYSENTER_ESP 0x175
|
||||
#define IA32_MSR_SYSENTER_EIP 0x176
|
||||
#define IA32_MSR_PERF_STATUS 0x198
|
||||
#define IA32_MSR_PERF_CTL 0x199
|
||||
#define IA32_MSR_TURBO_RATIO_LIMIT 0x1ad
|
||||
#define IA32_MSR_ENERGY_PERF_BIAS 0x1b0
|
||||
#define IA32_MSR_MTRR_DEFAULT_TYPE 0x2ff
|
||||
#define IA32_MSR_MTRR_PHYSICAL_BASE_0 0x200
|
||||
@ -152,6 +163,10 @@
|
||||
#define IA32_FEATURE_EXT_RDRND (1 << 30) // RDRAND instruction
|
||||
#define IA32_FEATURE_EXT_HYPERVISOR (1 << 31) // Running on a hypervisor
|
||||
|
||||
// x86 features from cpuid eax 0x80000001, ecx register (AMD)
|
||||
#define IA32_FEATURE_AMD_EXT_CMPLEGACY (1 << 1) // Core MP legacy mode
|
||||
#define IA32_FEATURE_AMD_EXT_TOPOLOGY (1 << 22) // Topology extensions
|
||||
|
||||
// x86 features from cpuid eax 0x80000001, edx register (AMD)
|
||||
// only care about the ones that are unique to this register
|
||||
#define IA32_FEATURE_AMD_EXT_SYSCALL (1 << 11) // SYSCALL/SYSRET
|
||||
@ -170,6 +185,10 @@
|
||||
| IA32_FEATURE_AMD_EXT_RDTSCP \
|
||||
| IA32_FEATURE_AMD_EXT_LONG)
|
||||
|
||||
// x86 defined features from cpuid eax 5, ecx register
|
||||
#define IA32_FEATURE_POWER_MWAIT (1 << 0)
|
||||
#define IA32_FEATURE_INTERRUPT_MWAIT (1 << 1)
|
||||
|
||||
// x86 defined features from cpuid eax 6, eax register
|
||||
// reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 5-11)
|
||||
#define IA32_FEATURE_DTS (1 << 0) //Digital Thermal Sensor
|
||||
@ -184,6 +203,9 @@
|
||||
#define IA32_FEATURE_APERFMPERF (1 << 0) //IA32_APERF, IA32_MPERF
|
||||
#define IA32_FEATURE_EPB (1 << 3) //IA32_ENERGY_PERF_BIAS
|
||||
|
||||
// x86 defined features from cpuid eax 0x80000007, edx register
|
||||
#define IA32_FEATURE_INVARIANT_TSC (1 << 8)
|
||||
|
||||
// cr4 flags
|
||||
#define IA32_CR4_PAE (1UL << 5)
|
||||
#define IA32_CR4_GLOBAL_PAGES (1UL << 7)
|
||||
@ -265,9 +287,12 @@ typedef struct x86_cpu_module_info {
|
||||
enum x86_feature_type {
|
||||
FEATURE_COMMON = 0, // cpuid eax=1, ecx register
|
||||
FEATURE_EXT, // cpuid eax=1, edx register
|
||||
FEATURE_EXT_AMD_ECX, // cpuid eax=0x80000001, ecx register (AMD)
|
||||
FEATURE_EXT_AMD, // cpuid eax=0x80000001, edx register (AMD)
|
||||
FEATURE_5_ECX, // cpuid eax=5, ecx register
|
||||
FEATURE_6_EAX, // cpuid eax=6, eax registers
|
||||
FEATURE_6_ECX, // cpuid eax=6, ecx registers
|
||||
FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register
|
||||
|
||||
FEATURE_NUM
|
||||
};
|
||||
@ -301,6 +326,8 @@ typedef struct arch_cpu_info {
|
||||
int model;
|
||||
int extended_model;
|
||||
|
||||
uint32 logical_apic_id;
|
||||
|
||||
struct X86PagingStructures* active_paging_structures;
|
||||
|
||||
size_t dr6; // temporary storage for debug registers (cf.
|
||||
@ -310,13 +337,11 @@ typedef struct arch_cpu_info {
|
||||
struct tss tss;
|
||||
#ifndef __x86_64__
|
||||
struct tss double_fault_tss;
|
||||
void* kernel_tls;
|
||||
#endif
|
||||
} arch_cpu_info;
|
||||
|
||||
|
||||
#undef PAUSE
|
||||
#define PAUSE() asm volatile ("pause;")
|
||||
|
||||
#define nop() __asm__ ("nop"::)
|
||||
|
||||
#define x86_read_cr0() ({ \
|
||||
@ -410,6 +435,9 @@ typedef struct arch_cpu_info {
|
||||
})
|
||||
|
||||
|
||||
extern void (*gCpuIdleFunc)(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -462,6 +490,20 @@ void x86_fnsave_swap(void* oldFpuState, const void* newFpuState);
|
||||
#endif
|
||||
|
||||
|
||||
static inline void
|
||||
arch_cpu_idle(void)
|
||||
{
|
||||
gCpuIdleFunc();
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
arch_cpu_pause(void)
|
||||
{
|
||||
asm volatile("pause" : : : "memory");
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C" {
|
||||
#endif
|
||||
|
@ -11,6 +11,13 @@
|
||||
#define NUM_IO_VECTORS (256 - ARCH_INTERRUPT_BASE)
|
||||
|
||||
|
||||
enum irq_source {
|
||||
IRQ_SOURCE_INVALID,
|
||||
IRQ_SOURCE_IOAPIC,
|
||||
IRQ_SOURCE_MSI,
|
||||
};
|
||||
|
||||
|
||||
static inline void
|
||||
arch_int_enable_interrupts_inline(void)
|
||||
{
|
||||
@ -68,9 +75,12 @@ typedef struct interrupt_controller_s {
|
||||
bool (*is_spurious_interrupt)(int32 num);
|
||||
bool (*is_level_triggered_interrupt)(int32 num);
|
||||
bool (*end_of_interrupt)(int32 num);
|
||||
void (*assign_interrupt_to_cpu)(int32 num, int32 cpu);
|
||||
} interrupt_controller;
|
||||
|
||||
|
||||
void x86_set_irq_source(int irq, irq_source source);
|
||||
|
||||
void arch_int_set_interrupt_controller(const interrupt_controller &controller);
|
||||
|
||||
#endif // __cplusplus
|
||||
|
@ -40,8 +40,8 @@ typedef struct {
|
||||
uint32 apic_phys;
|
||||
FixedWidthPointer<void> apic;
|
||||
uint32 ioapic_phys;
|
||||
uint32 cpu_apic_id[MAX_BOOT_CPUS];
|
||||
uint32 cpu_apic_version[MAX_BOOT_CPUS];
|
||||
uint32 cpu_apic_id[SMP_MAX_CPUS];
|
||||
uint32 cpu_apic_version[SMP_MAX_CPUS];
|
||||
// hpet stuff
|
||||
uint32 hpet_phys;
|
||||
FixedWidthPointer<void> hpet;
|
||||
|
@ -99,4 +99,18 @@ enum {
|
||||
MP_INTR_TYPE_ExtINT,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
uint32 x86_get_cpu_apic_id(int32 cpu);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_ARCH_SMP_H */
|
||||
|
@ -12,7 +12,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t get_current_cpuid(cpuid_info* info, uint32 eax);
|
||||
status_t get_current_cpuid(cpuid_info* info, uint32 eax, uint32 ecx);
|
||||
uint32 get_eflags(void);
|
||||
void set_eflags(uint32 value);
|
||||
|
||||
|
@ -30,9 +30,6 @@ void x86_restart_syscall(struct iframe* frame);
|
||||
void x86_set_tls_context(Thread* thread);
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
|
||||
static inline Thread*
|
||||
arch_thread_get_current_thread(void)
|
||||
{
|
||||
@ -42,6 +39,9 @@ arch_thread_get_current_thread(void)
|
||||
}
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
|
||||
static inline void
|
||||
arch_thread_set_current_thread(Thread* t)
|
||||
{
|
||||
@ -59,18 +59,10 @@ arch_thread_set_current_thread(Thread* t)
|
||||
void arch_syscall_64_bit_return_value(void);
|
||||
|
||||
|
||||
static inline Thread*
|
||||
arch_thread_get_current_thread(void)
|
||||
{
|
||||
Thread* t = (Thread*)x86_read_dr3();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
arch_thread_set_current_thread(Thread* t)
|
||||
{
|
||||
x86_write_dr3(t);
|
||||
asm volatile("mov %0, %%gs:0" : : "r" (t) : "memory");
|
||||
}
|
||||
|
||||
|
||||
@ -82,3 +74,4 @@ arch_thread_set_current_thread(Thread* t)
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL_ARCH_x86_THREAD_H */
|
||||
|
||||
|
@ -9,12 +9,7 @@
|
||||
#define ARCH_INIT_USER_DEBUG x86_init_user_debug
|
||||
|
||||
// number of breakpoints the CPU supports
|
||||
// On 32-bit, DR3 is used to hold the Thread*.
|
||||
#ifdef __x86_64__
|
||||
# define X86_BREAKPOINT_COUNT 4
|
||||
#else
|
||||
# define X86_BREAKPOINT_COUNT 3
|
||||
#endif
|
||||
#define X86_BREAKPOINT_COUNT 4
|
||||
|
||||
// debug status register DR6
|
||||
enum {
|
||||
|
@ -9,6 +9,10 @@
|
||||
#define _KERNEL_ARCH_x86_DESCRIPTORS_H
|
||||
|
||||
|
||||
#define DPL_KERNEL 0
|
||||
#define DPL_USER 3
|
||||
|
||||
|
||||
#ifndef _ASSEMBLER
|
||||
|
||||
|
||||
@ -18,11 +22,6 @@
|
||||
struct kernel_args;
|
||||
|
||||
|
||||
enum descriptor_privilege_levels {
|
||||
DPL_KERNEL = 0,
|
||||
DPL_USER = 3,
|
||||
};
|
||||
|
||||
enum descriptor_types {
|
||||
// segment types
|
||||
DT_CODE_EXECUTE_ONLY = 0x8,
|
||||
@ -48,6 +47,7 @@ enum gate_types {
|
||||
};
|
||||
|
||||
|
||||
void x86_descriptors_preboot_init_percpu(kernel_args* args, int cpu);
|
||||
void x86_descriptors_init(kernel_args* args);
|
||||
void x86_descriptors_init_percpu(kernel_args* args, int cpu);
|
||||
status_t x86_descriptors_init_post_vm(kernel_args* args);
|
||||
|
@ -28,5 +28,6 @@ bool msi_supported();
|
||||
status_t msi_allocate_vectors(uint8 count, uint8 *startVector,
|
||||
uint64 *address, uint16 *data);
|
||||
void msi_free_vectors(uint8 count, uint8 startVector);
|
||||
void msi_assign_interrupt_to_cpu(uint8 irq, int32 cpu);
|
||||
|
||||
#endif // _KERNEL_ARCH_x86_MSI_H
|
||||
|
@ -59,7 +59,7 @@ typedef struct kernel_args {
|
||||
uint64 ignored_physical_memory;
|
||||
|
||||
uint32 num_cpus;
|
||||
addr_range cpu_kstack[MAX_BOOT_CPUS];
|
||||
addr_range cpu_kstack[SMP_MAX_CPUS];
|
||||
|
||||
// boot volume KMessage data
|
||||
FixedWidthPointer<void> boot_volume;
|
||||
|
@ -15,8 +15,8 @@
|
||||
#include <util/FixedWidthPointer.h>
|
||||
|
||||
|
||||
// must match SMP_MAX_CPUS in arch_smp.h
|
||||
#define MAX_BOOT_CPUS 8
|
||||
#define SMP_MAX_CPUS 64
|
||||
|
||||
#define MAX_PHYSICAL_MEMORY_RANGE 32
|
||||
#define MAX_PHYSICAL_ALLOCATED_RANGE 32
|
||||
#define MAX_VIRTUAL_ALLOCATED_RANGE 32
|
||||
|
@ -56,19 +56,13 @@ public:
|
||||
|
||||
void Publish(const void* object,
|
||||
const char* objectType);
|
||||
void Unpublish(bool schedulerLocked = false);
|
||||
void Unpublish();
|
||||
|
||||
inline void NotifyOne(bool schedulerLocked = false,
|
||||
status_t result = B_OK);
|
||||
inline void NotifyAll(bool schedulerLocked = false,
|
||||
status_t result = B_OK);
|
||||
inline void NotifyOne(status_t result = B_OK);
|
||||
inline void NotifyAll(status_t result = B_OK);
|
||||
|
||||
static void NotifyOne(const void* object,
|
||||
bool schedulerLocked = false,
|
||||
status_t result = B_OK);
|
||||
static void NotifyAll(const void* object,
|
||||
bool schedulerLocked = false,
|
||||
status_t result = B_OK);
|
||||
static void NotifyOne(const void* object, status_t result);
|
||||
static void NotifyAll(const void* object, status_t result);
|
||||
// (both methods) caller must ensure that
|
||||
// the variable is not unpublished
|
||||
// concurrently
|
||||
@ -86,8 +80,7 @@ public:
|
||||
void Dump() const;
|
||||
|
||||
private:
|
||||
void _Notify(bool all, bool schedulerLocked,
|
||||
status_t result);
|
||||
void _Notify(bool all, status_t result);
|
||||
void _NotifyLocked(bool all, status_t result);
|
||||
|
||||
protected:
|
||||
@ -124,16 +117,16 @@ ConditionVariableEntry::~ConditionVariableEntry()
|
||||
|
||||
|
||||
inline void
|
||||
ConditionVariable::NotifyOne(bool schedulerLocked, status_t result)
|
||||
ConditionVariable::NotifyOne(status_t result)
|
||||
{
|
||||
_Notify(false, schedulerLocked, result);
|
||||
_Notify(false, result);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
ConditionVariable::NotifyAll(bool schedulerLocked, status_t result)
|
||||
ConditionVariable::NotifyAll(status_t result)
|
||||
{
|
||||
_Notify(true, schedulerLocked, result);
|
||||
_Notify(true, result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,15 +11,12 @@
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <int.h>
|
||||
#include <smp.h>
|
||||
#include <timer.h>
|
||||
#include <arch/cpu.h>
|
||||
|
||||
|
||||
// define PAUSE, if not done in arch/cpu.h
|
||||
#ifndef PAUSE
|
||||
# define PAUSE()
|
||||
#endif
|
||||
#include <scheduler.h>
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
@ -31,20 +28,43 @@ namespace BKernel {
|
||||
using BKernel::Thread;
|
||||
|
||||
|
||||
typedef enum cpu_topology_level {
|
||||
CPU_TOPOLOGY_SMT,
|
||||
CPU_TOPOLOGY_CORE,
|
||||
CPU_TOPOLOGY_PACKAGE,
|
||||
//
|
||||
CPU_TOPOLOGY_LEVELS
|
||||
} cpu_topology_level;
|
||||
|
||||
typedef struct cpu_topology_node {
|
||||
cpu_topology_level level;
|
||||
|
||||
int id;
|
||||
|
||||
cpu_topology_node** children;
|
||||
int children_count;
|
||||
} cpu_topology_node;
|
||||
|
||||
|
||||
/* CPU local data structure */
|
||||
|
||||
typedef struct cpu_ent {
|
||||
int cpu_num;
|
||||
|
||||
// thread.c: used to force a reschedule at quantum expiration time
|
||||
int preempted;
|
||||
bool preempted;
|
||||
timer quantum_timer;
|
||||
|
||||
// keeping track of CPU activity
|
||||
seqlock active_time_lock;
|
||||
bigtime_t active_time;
|
||||
bigtime_t irq_time;
|
||||
bigtime_t interrupt_time;
|
||||
bigtime_t last_kernel_time;
|
||||
bigtime_t last_user_time;
|
||||
|
||||
int32 ici_counter;
|
||||
|
||||
// used in the kernel debugger
|
||||
addr_t fault_handler;
|
||||
addr_t fault_handler_stack_pointer;
|
||||
@ -53,16 +73,24 @@ typedef struct cpu_ent {
|
||||
Thread* running_thread;
|
||||
Thread* previous_thread;
|
||||
bool invoke_scheduler;
|
||||
bool invoke_scheduler_if_idle;
|
||||
bool disabled;
|
||||
|
||||
// CPU topology information
|
||||
int topology_id[CPU_TOPOLOGY_LEVELS];
|
||||
int cache_id[CPU_MAX_CACHE_LEVEL];
|
||||
|
||||
// IRQs assigned to this CPU
|
||||
struct list irqs;
|
||||
spinlock irqs_lock;
|
||||
|
||||
// arch-specific stuff
|
||||
arch_cpu_info arch;
|
||||
} cpu_ent __attribute__((aligned(64)));
|
||||
arch_cpu_info arch;
|
||||
} cpu_ent CACHE_LINE_ALIGN;
|
||||
|
||||
|
||||
//extern cpu_ent gCPU[MAX_BOOT_CPUS];
|
||||
extern cpu_ent gCPU[];
|
||||
extern uint32 gCPUCacheLevelCount;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -79,6 +107,25 @@ bigtime_t cpu_get_active_time(int32 cpu);
|
||||
cpu_ent *get_cpu_struct(void);
|
||||
extern inline cpu_ent *get_cpu_struct(void) { return &gCPU[smp_get_current_cpu()]; }
|
||||
|
||||
status_t cpu_build_topology_tree(void);
|
||||
const cpu_topology_node* get_cpu_topology(void);
|
||||
|
||||
void cpu_set_scheduler_mode(enum scheduler_mode mode);
|
||||
|
||||
status_t increase_cpu_performance(int delta);
|
||||
status_t decrease_cpu_performance(int delta);
|
||||
|
||||
void cpu_idle(void);
|
||||
void cpu_wait(int32* variable, int32 test);
|
||||
|
||||
|
||||
static inline void
|
||||
cpu_pause(void)
|
||||
{
|
||||
arch_cpu_pause();
|
||||
}
|
||||
|
||||
|
||||
void _user_clear_caches(void *address, size_t length, uint32 flags);
|
||||
bool _user_cpu_enabled(int32 cpu);
|
||||
status_t _user_set_cpu_enabled(int32 cpu, bool enabled);
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <KernelExport.h>
|
||||
#include <arch/int.h>
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
// private install_io_interrupt_handler() flags
|
||||
#define B_NO_LOCK_VECTOR 0x100
|
||||
#define B_NO_HANDLED_INFO 0x200
|
||||
@ -19,6 +21,28 @@
|
||||
struct kernel_args;
|
||||
|
||||
|
||||
enum interrupt_type {
|
||||
INTERRUPT_TYPE_EXCEPTION,
|
||||
INTERRUPT_TYPE_IRQ,
|
||||
INTERRUPT_TYPE_LOCAL_IRQ,
|
||||
INTERRUPT_TYPE_SYSCALL,
|
||||
INTERRUPT_TYPE_ICI,
|
||||
INTERRUPT_TYPE_UNKNOWN
|
||||
};
|
||||
|
||||
struct irq_assignment {
|
||||
list_link link;
|
||||
|
||||
uint32 irq;
|
||||
uint32 count;
|
||||
|
||||
int32 handlers_count;
|
||||
|
||||
int32 load;
|
||||
int32 cpu;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -53,8 +77,12 @@ are_interrupts_enabled(void)
|
||||
#define restore_interrupts(status) arch_int_restore_interrupts(status)
|
||||
|
||||
|
||||
status_t reserve_io_interrupt_vectors(long count, long startVector);
|
||||
status_t allocate_io_interrupt_vectors(long count, long *startVector);
|
||||
status_t reserve_io_interrupt_vectors(long count, long startVector,
|
||||
enum interrupt_type type);
|
||||
status_t allocate_io_interrupt_vectors(long count, long *startVector,
|
||||
enum interrupt_type type);
|
||||
void free_io_interrupt_vectors(long count, long startVector);
|
||||
|
||||
void assign_io_interrupt_to_cpu(long vector, int32 cpu);
|
||||
|
||||
#endif /* _KERNEL_INT_H */
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013, Paweł Dziepak, pdziepak@quarnos.org.
|
||||
* Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2005-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
@ -17,78 +18,69 @@ struct scheduling_analysis;
|
||||
struct SchedulerListener;
|
||||
|
||||
|
||||
struct scheduler_ops {
|
||||
/*! Enqueues the thread in the ready-to-run queue.
|
||||
The caller must hold the scheduler lock (with disabled interrupts).
|
||||
*/
|
||||
void (*enqueue_in_run_queue)(Thread* thread);
|
||||
|
||||
/*! Selects a thread from the ready-to-run queue and, if that's not the
|
||||
calling thread, switches the current CPU's context to run the selected
|
||||
thread.
|
||||
If it's the same thread, the thread will just continue to run.
|
||||
In either case, unless the thread is dead or is sleeping/waiting
|
||||
indefinitely, the function will eventually return.
|
||||
The caller must hold the scheduler lock (with disabled interrupts).
|
||||
*/
|
||||
void (*reschedule)(void);
|
||||
|
||||
/*! Sets the given thread's priority.
|
||||
The thread may be running or may be in the ready-to-run queue.
|
||||
The caller must hold the scheduler lock (with disabled interrupts).
|
||||
*/
|
||||
void (*set_thread_priority)(Thread* thread, int32 priority);
|
||||
bigtime_t (*estimate_max_scheduling_latency)(Thread* thread);
|
||||
|
||||
/*! Called when the Thread structure is first created.
|
||||
Per-thread housekeeping resources can be allocated.
|
||||
Interrupts must be enabled.
|
||||
*/
|
||||
status_t (*on_thread_create)(Thread* thread, bool idleThread);
|
||||
|
||||
/*! Called when a Thread structure is initialized and made ready for
|
||||
use.
|
||||
The per-thread housekeeping data structures are reset, if needed.
|
||||
The caller must hold the scheduler lock (with disabled interrupts).
|
||||
*/
|
||||
void (*on_thread_init)(Thread* thread);
|
||||
|
||||
/*! Called when a Thread structure is freed.
|
||||
Frees up any per-thread resources allocated on the scheduler's part. The
|
||||
function may be called even if on_thread_create() failed.
|
||||
Interrupts must be enabled.
|
||||
*/
|
||||
void (*on_thread_destroy)(Thread* thread);
|
||||
|
||||
/*! Called in the early boot process to start thread scheduling on the
|
||||
current CPU.
|
||||
The function is called once for each CPU.
|
||||
Interrupts must be disabled, but the caller must not hold the scheduler
|
||||
lock.
|
||||
*/
|
||||
void (*start)(void);
|
||||
};
|
||||
|
||||
extern struct scheduler_ops* gScheduler;
|
||||
extern spinlock gSchedulerLock;
|
||||
|
||||
#define scheduler_enqueue_in_run_queue(thread) \
|
||||
gScheduler->enqueue_in_run_queue(thread)
|
||||
#define scheduler_set_thread_priority(thread, priority) \
|
||||
gScheduler->set_thread_priority(thread, priority)
|
||||
#define scheduler_reschedule() gScheduler->reschedule()
|
||||
#define scheduler_start() gScheduler->start()
|
||||
#define scheduler_on_thread_create(thread, idleThread) \
|
||||
gScheduler->on_thread_create(thread, idleThread)
|
||||
#define scheduler_on_thread_init(thread) \
|
||||
gScheduler->on_thread_init(thread)
|
||||
#define scheduler_on_thread_destroy(thread) \
|
||||
gScheduler->on_thread_destroy(thread)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! Enqueues the thread in the ready-to-run queue.
|
||||
The caller must hold the enqueued thread \c scheduler_lock.
|
||||
*/
|
||||
void scheduler_enqueue_in_run_queue(Thread* thread);
|
||||
|
||||
void scheduler_reschedule_ici(void);
|
||||
|
||||
/*! Selects a thread from the ready-to-run queue and, if that's not the
|
||||
calling thread, switches the current CPU's context to run the selected
|
||||
thread.
|
||||
If it's the same thread, the thread will just continue to run.
|
||||
In either case, unless the thread is dead or is sleeping/waiting
|
||||
indefinitely, the function will eventually return.
|
||||
The caller must hold the current thread \c scheduler_lock.
|
||||
*/
|
||||
void scheduler_reschedule(int32 next_state);
|
||||
|
||||
/*! Sets the given thread's priority.
|
||||
The thread may be running or may be in the ready-to-run queue.
|
||||
*/
|
||||
int32 scheduler_set_thread_priority(Thread* thread, int32 priority);
|
||||
|
||||
/*! Called when the Thread structure is first created.
|
||||
Per-thread housekeeping resources can be allocated.
|
||||
Interrupts must be enabled.
|
||||
*/
|
||||
status_t scheduler_on_thread_create(Thread* thread, bool idleThread);
|
||||
|
||||
/*! Called when a Thread structure is initialized and made ready for
|
||||
use.
|
||||
The per-thread housekeeping data structures are reset, if needed.
|
||||
*/
|
||||
void scheduler_on_thread_init(Thread* thread);
|
||||
|
||||
/*! Called when a Thread structure is freed.
|
||||
Frees up any per-thread resources allocated on the scheduler's part. The
|
||||
function may be called even if on_thread_create() failed.
|
||||
Interrupts must be enabled.
|
||||
*/
|
||||
void scheduler_on_thread_destroy(Thread* thread);
|
||||
|
||||
/*! Called in the early boot process to start thread scheduling on the
|
||||
current CPU.
|
||||
The function is called once for each CPU.
|
||||
*/
|
||||
void scheduler_start(void);
|
||||
|
||||
/*! Sets scheduler operation mode.
|
||||
*/
|
||||
status_t scheduler_set_operation_mode(scheduler_mode mode);
|
||||
|
||||
/*! Dumps scheduler specific thread information.
|
||||
*/
|
||||
void scheduler_dump_thread_data(Thread* thread);
|
||||
|
||||
void scheduler_new_thread_entry(Thread* thread);
|
||||
|
||||
void scheduler_set_cpu_enabled(int32 cpu, bool enabled);
|
||||
|
||||
void scheduler_add_listener(struct SchedulerListener* listener);
|
||||
void scheduler_remove_listener(struct SchedulerListener* listener);
|
||||
|
||||
@ -99,6 +91,9 @@ bigtime_t _user_estimate_max_scheduling_latency(thread_id thread);
|
||||
status_t _user_analyze_scheduling(bigtime_t from, bigtime_t until, void* buffer,
|
||||
size_t size, struct scheduling_analysis* analysis);
|
||||
|
||||
status_t _user_set_scheduler_mode(int32 mode);
|
||||
int32 _user_get_scheduler_mode(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -111,7 +106,7 @@ static inline void
|
||||
scheduler_reschedule_if_necessary_locked()
|
||||
{
|
||||
if (gCPU[smp_get_current_cpu()].invoke_scheduler)
|
||||
scheduler_reschedule();
|
||||
scheduler_reschedule(B_THREAD_READY);
|
||||
}
|
||||
|
||||
|
||||
@ -123,11 +118,14 @@ scheduler_reschedule_if_necessary()
|
||||
{
|
||||
if (are_interrupts_enabled()) {
|
||||
cpu_status state = disable_interrupts();
|
||||
acquire_spinlock(&gSchedulerLock);
|
||||
|
||||
Thread* thread = get_cpu_struct()->running_thread;
|
||||
acquire_spinlock(&thread->scheduler_lock);
|
||||
|
||||
scheduler_reschedule_if_necessary_locked();
|
||||
|
||||
release_spinlock(&gSchedulerLock);
|
||||
release_spinlock(&thread->scheduler_lock);
|
||||
|
||||
restore_interrupts(state);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,11 @@ status_t system_info_init(struct kernel_args *args);
|
||||
status_t system_notifications_init();
|
||||
const char* get_haiku_revision(void);
|
||||
|
||||
status_t _user_get_system_info(system_info *userInfo, size_t size);
|
||||
status_t _user_get_system_info(system_info *userInfo);
|
||||
status_t _user_get_cpu_info(uint32 firstCPU, uint32 cpuCount, cpu_info* info);
|
||||
status_t _user_get_cpu_topology_info(cpu_topology_node_info* topologyInfos,
|
||||
uint32* topologyInfoCount);
|
||||
|
||||
status_t _user_get_system_info_etc(int32 id, void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
|
@ -34,7 +34,7 @@ struct SchedulerListener : DoublyLinkedListLinkImpl<SchedulerListener> {
|
||||
|
||||
typedef DoublyLinkedList<SchedulerListener> SchedulerListenerList;
|
||||
extern SchedulerListenerList gSchedulerListeners;
|
||||
// guarded by the thread spinlock
|
||||
extern spinlock gSchedulerListenersLock;
|
||||
|
||||
|
||||
template<typename Parameter1>
|
||||
|
57
headers/private/kernel/load_tracking.h
Normal file
57
headers/private/kernel/load_tracking.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013 Paweł Dziepak, pdziepak@quarnos.org.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_LOAD_TRACKING_H
|
||||
#define _KERNEL_LOAD_TRACKING_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
const int32 kMaxLoad = 1000;
|
||||
const bigtime_t kLoadMeasureInterval = 50000;
|
||||
const bigtime_t kIntervalInaccuracy = kLoadMeasureInterval / 4;
|
||||
|
||||
|
||||
static inline int32
|
||||
compute_load(bigtime_t& measureTime, bigtime_t& measureActiveTime, int32& load,
|
||||
bigtime_t now)
|
||||
{
|
||||
if (measureTime == 0) {
|
||||
measureTime = now;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bigtime_t deltaTime = now - measureTime;
|
||||
|
||||
if (deltaTime < kLoadMeasureInterval)
|
||||
return -1;
|
||||
|
||||
int32 oldLoad = load;
|
||||
ASSERT(oldLoad >= 0 && oldLoad <= kMaxLoad);
|
||||
|
||||
int32 newLoad = measureActiveTime * kMaxLoad;
|
||||
newLoad /= max_c(deltaTime, 1);
|
||||
newLoad = max_c(min_c(newLoad, kMaxLoad), 0);
|
||||
|
||||
measureActiveTime = 0;
|
||||
measureTime = now;
|
||||
|
||||
deltaTime += kIntervalInaccuracy;
|
||||
int n = deltaTime / kLoadMeasureInterval;
|
||||
ASSERT(n > 0);
|
||||
|
||||
if (n > 10)
|
||||
load = newLoad;
|
||||
else {
|
||||
newLoad *= (1 << n) - 1;
|
||||
load = (load + newLoad) / (1 << n);
|
||||
ASSERT(load >= 0 && load <= kMaxLoad);
|
||||
}
|
||||
|
||||
return oldLoad;
|
||||
}
|
||||
|
||||
|
||||
#endif // _KERNEL_LOAD_TRACKING_H
|
@ -9,7 +9,10 @@
|
||||
#ifndef _KERNEL_LOCK_H
|
||||
#define _KERNEL_LOCK_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <arch/atomic.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
@ -18,6 +21,7 @@ struct mutex_waiter;
|
||||
typedef struct mutex {
|
||||
const char* name;
|
||||
struct mutex_waiter* waiters;
|
||||
spinlock lock;
|
||||
#if KDEBUG
|
||||
thread_id holder;
|
||||
#else
|
||||
@ -44,8 +48,9 @@ struct rw_lock_waiter;
|
||||
typedef struct rw_lock {
|
||||
const char* name;
|
||||
struct rw_lock_waiter* waiters;
|
||||
spinlock lock;
|
||||
thread_id holder;
|
||||
vint32 count;
|
||||
int32 count;
|
||||
int32 owner_count;
|
||||
int16 active_readers;
|
||||
// Only > 0 while a writer is waiting: number
|
||||
@ -88,14 +93,17 @@ typedef struct rw_lock {
|
||||
|
||||
// static initializers
|
||||
#if KDEBUG
|
||||
# define MUTEX_INITIALIZER(name) { name, NULL, -1, 0 }
|
||||
# define MUTEX_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, -1, 0 }
|
||||
# define RECURSIVE_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), 0 }
|
||||
#else
|
||||
# define MUTEX_INITIALIZER(name) { name, NULL, 0, 0, 0 }
|
||||
# define MUTEX_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, 0, 0, 0 }
|
||||
# define RECURSIVE_LOCK_INITIALIZER(name) { MUTEX_INITIALIZER(name), -1, 0 }
|
||||
#endif
|
||||
|
||||
#define RW_LOCK_INITIALIZER(name) { name, NULL, -1, 0, 0, 0 }
|
||||
#define RW_LOCK_INITIALIZER(name) \
|
||||
{ name, NULL, B_SPINLOCK_INITIALIZER, -1, 0, 0, 0 }
|
||||
|
||||
|
||||
#if KDEBUG
|
||||
@ -144,11 +152,11 @@ extern status_t mutex_switch_from_read_lock(rw_lock* from, mutex* to);
|
||||
extern status_t _rw_lock_read_lock(rw_lock* lock);
|
||||
extern status_t _rw_lock_read_lock_with_timeout(rw_lock* lock,
|
||||
uint32 timeoutFlags, bigtime_t timeout);
|
||||
extern void _rw_lock_read_unlock(rw_lock* lock, bool schedulerLocked);
|
||||
extern void _rw_lock_write_unlock(rw_lock* lock, bool schedulerLocked);
|
||||
extern void _rw_lock_read_unlock(rw_lock* lock);
|
||||
extern void _rw_lock_write_unlock(rw_lock* lock);
|
||||
|
||||
extern status_t _mutex_lock(mutex* lock, bool schedulerLocked);
|
||||
extern void _mutex_unlock(mutex* lock, bool schedulerLocked);
|
||||
extern status_t _mutex_lock(mutex* lock, void* locker);
|
||||
extern void _mutex_unlock(mutex* lock);
|
||||
extern status_t _mutex_trylock(mutex* lock);
|
||||
extern status_t _mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags,
|
||||
bigtime_t timeout);
|
||||
@ -191,7 +199,7 @@ rw_lock_read_unlock(rw_lock* lock)
|
||||
#else
|
||||
int32 oldCount = atomic_add(&lock->count, -1);
|
||||
if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
|
||||
_rw_lock_read_unlock(lock, false);
|
||||
_rw_lock_read_unlock(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -199,7 +207,7 @@ rw_lock_read_unlock(rw_lock* lock)
|
||||
static inline void
|
||||
rw_lock_write_unlock(rw_lock* lock)
|
||||
{
|
||||
_rw_lock_write_unlock(lock, false);
|
||||
_rw_lock_write_unlock(lock);
|
||||
}
|
||||
|
||||
|
||||
@ -207,23 +215,10 @@ static inline status_t
|
||||
mutex_lock(mutex* lock)
|
||||
{
|
||||
#if KDEBUG
|
||||
return _mutex_lock(lock, false);
|
||||
return _mutex_lock(lock, NULL);
|
||||
#else
|
||||
if (atomic_add(&lock->count, -1) < 0)
|
||||
return _mutex_lock(lock, false);
|
||||
return B_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline status_t
|
||||
mutex_lock_threads_locked(mutex* lock)
|
||||
{
|
||||
#if KDEBUG
|
||||
return _mutex_lock(lock, true);
|
||||
#else
|
||||
if (atomic_add(&lock->count, -1) < 0)
|
||||
return _mutex_lock(lock, true);
|
||||
return _mutex_lock(lock, NULL);
|
||||
return B_OK;
|
||||
#endif
|
||||
}
|
||||
@ -261,7 +256,7 @@ mutex_unlock(mutex* lock)
|
||||
#if !KDEBUG
|
||||
if (atomic_add(&lock->count, 1) < -1)
|
||||
#endif
|
||||
_mutex_unlock(lock, false);
|
||||
_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,8 +9,15 @@
|
||||
#define KERNEL_SMP_H
|
||||
|
||||
|
||||
#include <arch/atomic.h>
|
||||
#include <boot/kernel_args.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
|
||||
@ -22,8 +29,7 @@ enum {
|
||||
SMP_MSG_GLOBAL_INVALIDATE_PAGES,
|
||||
SMP_MSG_CPU_HALT,
|
||||
SMP_MSG_CALL_FUNCTION,
|
||||
SMP_MSG_RESCHEDULE,
|
||||
SMP_MSG_RESCHEDULE_IF_IDLE
|
||||
SMP_MSG_RESCHEDULE
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -32,10 +38,28 @@ enum {
|
||||
SMP_MSG_FLAG_FREE_ARG = 0x2,
|
||||
};
|
||||
|
||||
typedef uint32 cpu_mask_t;
|
||||
|
||||
typedef void (*smp_call_func)(addr_t data1, int32 currentCPU, addr_t data2, addr_t data3);
|
||||
|
||||
class CPUSet {
|
||||
public:
|
||||
inline CPUSet();
|
||||
|
||||
inline void ClearAll();
|
||||
inline void SetAll();
|
||||
|
||||
inline void SetBit(int32 cpu);
|
||||
inline void ClearBit(int32 cpu);
|
||||
|
||||
inline bool GetBit(int32 cpu) const;
|
||||
|
||||
inline bool IsEmpty() const;
|
||||
|
||||
private:
|
||||
static const int kArraySize = ROUNDUP(SMP_MAX_CPUS, 32) / 32;
|
||||
|
||||
uint32 fBitmap[kArraySize];
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -48,10 +72,10 @@ status_t smp_per_cpu_init(struct kernel_args *args, int32 cpu);
|
||||
status_t smp_init_post_generic_syscalls(void);
|
||||
bool smp_trap_non_boot_cpus(int32 cpu, uint32* rendezVous);
|
||||
void smp_wake_up_non_boot_cpus(void);
|
||||
void smp_cpu_rendezvous(volatile uint32 *var, int current_cpu);
|
||||
void smp_cpu_rendezvous(uint32* var);
|
||||
void smp_send_ici(int32 targetCPU, int32 message, addr_t data, addr_t data2, addr_t data3,
|
||||
void *data_ptr, uint32 flags);
|
||||
void smp_send_multicast_ici(cpu_mask_t cpuMask, int32 message, addr_t data,
|
||||
void smp_send_multicast_ici(CPUSet& cpuMask, int32 message, addr_t data,
|
||||
addr_t data2, addr_t data3, void *data_ptr, uint32 flags);
|
||||
void smp_send_broadcast_ici(int32 message, addr_t data, addr_t data2, addr_t data3,
|
||||
void *data_ptr, uint32 flags);
|
||||
@ -69,6 +93,63 @@ int smp_intercpu_int_handler(int32 cpu);
|
||||
#endif
|
||||
|
||||
|
||||
inline
|
||||
CPUSet::CPUSet()
|
||||
{
|
||||
memset(fBitmap, 0, sizeof(fBitmap));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::ClearAll()
|
||||
{
|
||||
memset(fBitmap, 0, sizeof(fBitmap));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::SetAll()
|
||||
{
|
||||
memset(fBitmap, ~uint8(0), sizeof(fBitmap));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::SetBit(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
atomic_or(element, 1u << (cpu / kArraySize));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::ClearBit(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
atomic_and(element, ~uint32(1u << (cpu / kArraySize)));
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
CPUSet::GetBit(int32 cpu) const
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
return ((uint32)atomic_get(element) & (1u << (cpu / kArraySize))) != 0;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
CPUSet::IsEmpty() const
|
||||
{
|
||||
for (int i = 0; i < kArraySize; i++) {
|
||||
if (fBitmap[i] != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Unless spinlock debug features are enabled, try to inline
|
||||
// {acquire,release}_spinlock().
|
||||
#if !DEBUG_SPINLOCKS && !B_DEBUG_SPINLOCK_CONTENTION
|
||||
@ -77,7 +158,7 @@ int smp_intercpu_int_handler(int32 cpu);
|
||||
static inline bool
|
||||
try_acquire_spinlock_inline(spinlock* lock)
|
||||
{
|
||||
return atomic_or((int32*)lock, 1) == 0;
|
||||
return atomic_get_and_set((int32*)lock, 1) == 0;
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +174,7 @@ acquire_spinlock_inline(spinlock* lock)
|
||||
static inline void
|
||||
release_spinlock_inline(spinlock* lock)
|
||||
{
|
||||
atomic_and((int32*)lock, 0);
|
||||
atomic_set((int32*)lock, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -101,6 +182,108 @@ release_spinlock_inline(spinlock* lock)
|
||||
#define acquire_spinlock(lock) acquire_spinlock_inline(lock)
|
||||
#define release_spinlock(lock) release_spinlock_inline(lock)
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
return atomic_test_and_set(&lock->lock, 1u << 31, 0) == 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
acquire_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
if (try_acquire_write_spinlock(lock))
|
||||
return;
|
||||
acquire_write_spinlock(lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
release_write_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
atomic_set(&lock->lock, 0);
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
uint32 previous = atomic_add(&lock->lock, 1);
|
||||
return (previous & (1u << 31)) == 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
acquire_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
if (try_acquire_read_spinlock(lock))
|
||||
return;
|
||||
acquire_read_spinlock(lock);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
release_read_spinlock_inline(rw_spinlock* lock)
|
||||
{
|
||||
atomic_add(&lock->lock, -1);
|
||||
}
|
||||
|
||||
|
||||
#define try_acquire_read_spinlock(lock) try_acquire_read_spinlock_inline(lock)
|
||||
#define acquire_read_spinlock(lock) acquire_read_spinlock_inline(lock)
|
||||
#define release_read_spinlock(lock) release_read_spinlock_inline(lock)
|
||||
#define try_acquire_write_spinlock(lock) \
|
||||
try_acquire_write_spinlock(lock)
|
||||
#define acquire_write_spinlock(lock) acquire_write_spinlock_inline(lock)
|
||||
#define release_write_spinlock(lock) release_write_spinlock_inline(lock)
|
||||
|
||||
|
||||
static inline bool
|
||||
try_acquire_write_seqlock_inline(seqlock* lock) {
|
||||
bool succeed = try_acquire_spinlock(&lock->lock);
|
||||
if (succeed)
|
||||
atomic_add((int32*)&lock->count, 1);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
acquire_write_seqlock_inline(seqlock* lock) {
|
||||
acquire_spinlock(&lock->lock);
|
||||
atomic_add((int32*)&lock->count, 1);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
release_write_seqlock_inline(seqlock* lock) {
|
||||
atomic_add((int32*)&lock->count, 1);
|
||||
release_spinlock(&lock->lock);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
acquire_read_seqlock_inline(seqlock* lock) {
|
||||
return atomic_get((int32*)&lock->count);
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
release_read_seqlock_inline(seqlock* lock, uint32 count) {
|
||||
uint32 current = atomic_get((int32*)&lock->count);
|
||||
|
||||
return count % 2 == 0 && current == count;
|
||||
}
|
||||
|
||||
|
||||
#define try_acquire_write_seqlock(lock) try_acquire_write_seqlock_inline(lock)
|
||||
#define acquire_write_seqlock(lock) acquire_write_seqlock_inline(lock)
|
||||
#define release_write_seqlock(lock) release_write_seqlock_inline(lock)
|
||||
#define acquire_read_seqlock(lock) acquire_read_seqlock_inline(lock)
|
||||
#define release_read_seqlock(lock, count) \
|
||||
release_read_seqlock_inline(lock, count)
|
||||
|
||||
|
||||
#endif // !DEBUG_SPINLOCKS && !B_DEBUG_SPINLOCK_CONTENTION
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ thread_id load_image_etc(int32 argCount, const char* const* args,
|
||||
const char* const* env, int32 priority, team_id parentID, uint32 flags);
|
||||
|
||||
void team_set_job_control_state(Team* team, job_control_state newState,
|
||||
Signal* signal, bool threadsLocked);
|
||||
Signal* signal);
|
||||
void team_set_controlling_tty(int32 index);
|
||||
int32 team_get_controlling_tty();
|
||||
status_t team_set_foreground_process_group(int32 ttyIndex, pid_t processGroup);
|
||||
|
@ -11,12 +11,13 @@
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <thread_types.h>
|
||||
#include <arch/thread.h>
|
||||
|
||||
#include <arch/atomic.h>
|
||||
#include <arch/thread.h>
|
||||
// For the thread blocking inline functions only.
|
||||
#include <kscheduler.h>
|
||||
#include <ksignal.h>
|
||||
#include <thread_types.h>
|
||||
|
||||
|
||||
struct arch_fork_arg;
|
||||
@ -69,15 +70,13 @@ public:
|
||||
using BKernel::ThreadCreationAttributes;
|
||||
|
||||
|
||||
extern spinlock gThreadCreationLock;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void thread_enqueue(Thread *t, struct thread_queue *q);
|
||||
Thread *thread_lookat_queue(struct thread_queue *q);
|
||||
Thread *thread_dequeue(struct thread_queue *q);
|
||||
Thread *thread_dequeue_id(struct thread_queue *q, thread_id id);
|
||||
|
||||
void thread_at_kernel_entry(bigtime_t now);
|
||||
// called when the thread enters the kernel on behalf of the thread
|
||||
void thread_at_kernel_exit(void);
|
||||
@ -86,9 +85,11 @@ void thread_reset_for_exec(void);
|
||||
|
||||
status_t thread_init(struct kernel_args *args);
|
||||
status_t thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum);
|
||||
void thread_yield(bool force);
|
||||
void thread_yield(void);
|
||||
void thread_exit(void);
|
||||
|
||||
void thread_map(void (*function)(Thread* thread, void* data), void* data);
|
||||
|
||||
int32 thread_max_threads(void);
|
||||
int32 thread_used_threads(void);
|
||||
|
||||
@ -135,8 +136,7 @@ status_t deselect_thread(int32 object, struct select_info *info, bool kernel);
|
||||
|
||||
status_t thread_block();
|
||||
status_t thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout);
|
||||
status_t thread_block_with_timeout_locked(uint32 timeoutFlags,
|
||||
bigtime_t timeout);
|
||||
void thread_unblock(Thread* thread, status_t status);
|
||||
|
||||
// used in syscalls.c
|
||||
status_t _user_set_thread_priority(thread_id thread, int32 newPriority);
|
||||
@ -212,7 +212,7 @@ thread_is_interrupted(Thread* thread, uint32 flags)
|
||||
static inline bool
|
||||
thread_is_blocked(Thread* thread)
|
||||
{
|
||||
return thread->wait.status == 1;
|
||||
return atomic_get(&thread->wait.status) == 1;
|
||||
}
|
||||
|
||||
|
||||
@ -234,22 +234,22 @@ thread_is_blocked(Thread* thread)
|
||||
If a client lock other than the scheduler lock is used, this function must
|
||||
be called with that lock being held. Afterwards that lock should be dropped
|
||||
and the function that actually blocks the thread shall be invoked
|
||||
(thread_block[_locked]() or thread_block_with_timeout[_locked]()). In
|
||||
between these two steps no functionality that uses the thread blocking API
|
||||
for this thread shall be used.
|
||||
(thread_block[_locked]() or thread_block_with_timeout()). In between these
|
||||
two steps no functionality that uses the thread blocking API for this thread
|
||||
shall be used.
|
||||
|
||||
When the caller determines that the condition for unblocking the thread
|
||||
occurred, it calls thread_unblock_locked() to unblock the thread. At that
|
||||
time one of locks that are held when calling thread_prepare_to_block() must
|
||||
be held. Usually that would be the client lock. In two cases it generally
|
||||
isn't, however, since the unblocking code doesn't know about the client
|
||||
lock: 1. When thread_block_with_timeout[_locked]() had been used and the
|
||||
timeout occurs. 2. When thread_prepare_to_block() had been called with one
|
||||
or both of the \c B_CAN_INTERRUPT or \c B_KILL_CAN_INTERRUPT flags specified
|
||||
and someone calls thread_interrupt() that is supposed to wake up the thread.
|
||||
lock: 1. When thread_block_with_timeout() had been used and the timeout
|
||||
occurs. 2. When thread_prepare_to_block() had been called with one or both
|
||||
of the \c B_CAN_INTERRUPT or \c B_KILL_CAN_INTERRUPT flags specified and
|
||||
someone calls thread_interrupt() that is supposed to wake up the thread.
|
||||
In either of these two cases only the scheduler lock is held by the
|
||||
unblocking code. A timeout can only happen after
|
||||
thread_block_with_timeout_locked() has been called, but an interruption is
|
||||
thread_block_with_timeout() has been called, but an interruption is
|
||||
possible at any time. The client code must deal with those situations.
|
||||
|
||||
Generally blocking and unblocking threads proceed in the following manner:
|
||||
@ -333,39 +333,6 @@ thread_prepare_to_block(Thread* thread, uint32 flags, uint32 type,
|
||||
}
|
||||
|
||||
|
||||
/*! Blocks the current thread.
|
||||
|
||||
The thread is blocked until someone else unblock it. Must be called after a
|
||||
call to thread_prepare_to_block(). If the thread has already been unblocked
|
||||
after the previous call to thread_prepare_to_block(), this function will
|
||||
return immediately. Cf. the documentation of thread_prepare_to_block() for
|
||||
more details.
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
|
||||
\param thread The current thread.
|
||||
\return The error code passed to the unblocking function. thread_interrupt()
|
||||
uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
|
||||
successful while another error code indicates a failure (what that means
|
||||
depends on the client code).
|
||||
*/
|
||||
static inline status_t
|
||||
thread_block_locked(Thread* thread)
|
||||
{
|
||||
if (thread->wait.status == 1) {
|
||||
// check for signals, if interruptible
|
||||
if (thread_is_interrupted(thread, thread->wait.flags)) {
|
||||
thread->wait.status = B_INTERRUPTED;
|
||||
} else {
|
||||
thread->next_state = B_THREAD_WAITING;
|
||||
scheduler_reschedule();
|
||||
}
|
||||
}
|
||||
|
||||
return thread->wait.status;
|
||||
}
|
||||
|
||||
|
||||
/*! Unblocks the specified blocked thread.
|
||||
|
||||
If the thread is no longer waiting (e.g. because thread_unblock_locked() has
|
||||
@ -417,10 +384,12 @@ thread_unblock_locked(Thread* thread, status_t status)
|
||||
static inline status_t
|
||||
thread_interrupt(Thread* thread, bool kill)
|
||||
{
|
||||
if ((thread->wait.flags & B_CAN_INTERRUPT) != 0
|
||||
|| (kill && (thread->wait.flags & B_KILL_CAN_INTERRUPT) != 0)) {
|
||||
thread_unblock_locked(thread, B_INTERRUPTED);
|
||||
return B_OK;
|
||||
if (thread_is_blocked(thread)) {
|
||||
if ((thread->wait.flags & B_CAN_INTERRUPT) != 0
|
||||
|| (kill && (thread->wait.flags & B_KILL_CAN_INTERRUPT) != 0)) {
|
||||
thread_unblock_locked(thread, B_INTERRUPTED);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return B_NOT_ALLOWED;
|
||||
|
@ -57,12 +57,15 @@ struct cpu_ent;
|
||||
struct image; // defined in image.c
|
||||
struct io_context;
|
||||
struct realtime_sem_context; // defined in realtime_sem.cpp
|
||||
struct scheduler_thread_data;
|
||||
struct select_info;
|
||||
struct user_thread; // defined in libroot/user_thread.h
|
||||
struct VMAddressSpace;
|
||||
struct xsi_sem_context; // defined in xsi_semaphore.cpp
|
||||
|
||||
namespace Scheduler {
|
||||
struct ThreadData;
|
||||
}
|
||||
|
||||
namespace BKernel {
|
||||
struct Team;
|
||||
struct Thread;
|
||||
@ -242,10 +245,10 @@ struct Team : TeamThreadIteratorEntry<team_id>, KernelReferenceable,
|
||||
struct job_control_entry* job_control_entry;
|
||||
|
||||
VMAddressSpace *address_space;
|
||||
Thread *main_thread; // protected by fLock and the scheduler
|
||||
// lock (and the thread's lock), immutable
|
||||
Thread *main_thread; // protected by fLock, immutable
|
||||
// after first set
|
||||
Thread *thread_list; // protected by fLock and the scheduler lock
|
||||
Thread *thread_list; // protected by fLock, signal_lock and
|
||||
// gThreadCreationLock
|
||||
struct team_loading_info *loading_info; // protected by fLock
|
||||
struct list image_list; // protected by sImageMutex
|
||||
struct list watcher_list;
|
||||
@ -263,13 +266,13 @@ struct Team : TeamThreadIteratorEntry<team_id>, KernelReferenceable,
|
||||
|
||||
struct team_debug_info debug_info;
|
||||
|
||||
// protected by scheduler lock
|
||||
// protected by time_lock
|
||||
bigtime_t dead_threads_kernel_time;
|
||||
bigtime_t dead_threads_user_time;
|
||||
bigtime_t cpu_clock_offset;
|
||||
spinlock time_lock;
|
||||
|
||||
// user group information; protected by fLock, the *_uid/*_gid fields also
|
||||
// by the scheduler lock
|
||||
// user group information; protected by fLock
|
||||
uid_t saved_set_uid;
|
||||
uid_t real_uid;
|
||||
uid_t effective_uid;
|
||||
@ -290,6 +293,8 @@ struct Team : TeamThreadIteratorEntry<team_id>, KernelReferenceable,
|
||||
bool initialized; // true when the state has been initialized
|
||||
} exit;
|
||||
|
||||
spinlock signal_lock;
|
||||
|
||||
public:
|
||||
~Team();
|
||||
|
||||
@ -397,7 +402,7 @@ private:
|
||||
|
||||
BKernel::QueuedSignalsCounter* fQueuedSignalsCounter;
|
||||
BKernel::PendingSignals fPendingSignals;
|
||||
// protected by scheduler lock
|
||||
// protected by signal_lock
|
||||
struct sigaction fSignalActions[MAX_SIGNAL_NUMBER];
|
||||
// indexed signal - 1, protected by fLock
|
||||
|
||||
@ -405,7 +410,7 @@ private:
|
||||
TeamTimeUserTimerList fCPUTimeUserTimers;
|
||||
// protected by scheduler lock
|
||||
TeamUserTimeUserTimerList fUserTimeUserTimers;
|
||||
vint32 fUserDefinedTimerCount; // accessed atomically
|
||||
int32 fUserDefinedTimerCount; // accessed atomically
|
||||
};
|
||||
|
||||
|
||||
@ -416,20 +421,17 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, KernelReferenceable {
|
||||
int64 serial_number; // immutable after adding thread to hash
|
||||
Thread *hash_next; // protected by thread hash lock
|
||||
Thread *team_next; // protected by team lock and fLock
|
||||
Thread *queue_next; // protected by scheduler lock
|
||||
timer alarm; // protected by scheduler lock
|
||||
char name[B_OS_NAME_LENGTH]; // protected by fLock
|
||||
int32 priority; // protected by scheduler lock
|
||||
int32 next_priority; // protected by scheduler lock
|
||||
int32 io_priority; // protected by fLock
|
||||
int32 state; // protected by scheduler lock
|
||||
int32 next_state; // protected by scheduler lock
|
||||
struct cpu_ent *cpu; // protected by scheduler lock
|
||||
struct cpu_ent *previous_cpu; // protected by scheduler lock
|
||||
int32 pinned_to_cpu; // only accessed by this thread or in the
|
||||
// scheduler, when thread is not running
|
||||
spinlock scheduler_lock;
|
||||
|
||||
sigset_t sig_block_mask; // protected by scheduler lock,
|
||||
sigset_t sig_block_mask; // protected by team->signal_lock,
|
||||
// only modified by the thread itself
|
||||
sigset_t sigsuspend_original_unblocked_mask;
|
||||
// non-0 after a return from _user_sigsuspend(), containing the inverted
|
||||
@ -442,8 +444,8 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, KernelReferenceable {
|
||||
|
||||
bool in_kernel; // protected by time_lock, only written by
|
||||
// this thread
|
||||
bool was_yielded; // protected by scheduler lock
|
||||
struct scheduler_thread_data* scheduler_data; // protected by scheduler lock
|
||||
bool has_yielded; // protected by scheduler lock
|
||||
Scheduler::ThreadData* scheduler_data; // protected by scheduler lock
|
||||
|
||||
struct user_thread* user_thread; // write-protected by fLock, only
|
||||
// modified by the thread itself and
|
||||
@ -481,7 +483,8 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, KernelReferenceable {
|
||||
/* this field may only stay in debug builds in the future */
|
||||
|
||||
BKernel::Team *team; // protected by team lock, thread lock, scheduler
|
||||
// lock
|
||||
// lock, team_lock
|
||||
rw_spinlock team_lock;
|
||||
|
||||
struct {
|
||||
sem_id sem; // immutable after thread creation
|
||||
@ -514,7 +517,7 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, KernelReferenceable {
|
||||
bigtime_t user_time; // protected by time_lock
|
||||
bigtime_t kernel_time; // protected by time_lock
|
||||
bigtime_t last_time; // protected by time_lock
|
||||
bigtime_t cpu_clock_offset; // protected by scheduler lock
|
||||
bigtime_t cpu_clock_offset; // protected by time_lock
|
||||
|
||||
void (*post_interrupt_callback)(void*);
|
||||
void* post_interrupt_data;
|
||||
@ -604,11 +607,11 @@ private:
|
||||
mutex fLock;
|
||||
|
||||
BKernel::PendingSignals fPendingSignals;
|
||||
// protected by scheduler lock
|
||||
// protected by team->signal_lock
|
||||
|
||||
UserTimerList fUserTimers; // protected by fLock
|
||||
ThreadTimeUserTimerList fCPUTimeUserTimers;
|
||||
// protected by scheduler lock
|
||||
// protected by time_lock
|
||||
};
|
||||
|
||||
|
||||
@ -747,7 +750,7 @@ Thread::DequeuePendingSignal(sigset_t nonBlocked, Signal& buffer)
|
||||
|
||||
/*! Returns the thread's current total CPU time (kernel + user + offset).
|
||||
|
||||
The caller must hold the scheduler lock.
|
||||
The caller must hold \c time_lock.
|
||||
|
||||
\param ignoreCurrentRun If \c true and the thread is currently running,
|
||||
don't add the time since the last time \c last_time was updated. Should
|
||||
@ -762,7 +765,7 @@ Thread::CPUTime(bool ignoreCurrentRun) const
|
||||
|
||||
// If currently running, also add the time since the last check, unless
|
||||
// requested otherwise.
|
||||
if (!ignoreCurrentRun && cpu != NULL)
|
||||
if (!ignoreCurrentRun && last_time != 0)
|
||||
time += system_time() - last_time;
|
||||
|
||||
return time;
|
||||
@ -780,12 +783,6 @@ using BKernel::ProcessGroup;
|
||||
using BKernel::ProcessGroupList;
|
||||
|
||||
|
||||
struct thread_queue {
|
||||
Thread* head;
|
||||
Thread* tail;
|
||||
};
|
||||
|
||||
|
||||
#endif // !_ASSEMBLER
|
||||
|
||||
|
||||
|
@ -23,13 +23,8 @@ struct kernel_args;
|
||||
#define B_TIMER_USE_TIMER_STRUCT_TIMES 0x4000
|
||||
// For add_timer(): Use the timer::schedule_time (absolute time) and
|
||||
// timer::period values instead of the period parameter.
|
||||
#define B_TIMER_ACQUIRE_SCHEDULER_LOCK 0x8000
|
||||
// The timer hook is invoked with the scheduler lock held. When invoking
|
||||
// cancel_timer() with the scheduler lock held, too, this helps to avoid
|
||||
// race conditions.
|
||||
#define B_TIMER_FLAGS \
|
||||
(B_TIMER_USE_TIMER_STRUCT_TIMES | B_TIMER_ACQUIRE_SCHEDULER_LOCK \
|
||||
| B_TIMER_REAL_TIME_BASE)
|
||||
(B_TIMER_USE_TIMER_STRUCT_TIMES | B_TIMER_REAL_TIME_BASE)
|
||||
|
||||
/* Timer info structure */
|
||||
struct timer_info {
|
||||
|
@ -68,7 +68,7 @@ struct team_debug_info {
|
||||
thread_id causing_thread;
|
||||
// thread that caused the debugger to be attached; -1 for manual
|
||||
// debugger attachment (or no debugger installed)
|
||||
vint32 image_event;
|
||||
int32 image_event;
|
||||
// counter incremented whenever an image is created/deleted
|
||||
|
||||
struct ConditionVariable* debugger_changed_condition;
|
||||
|
@ -160,6 +160,144 @@ private:
|
||||
typedef AutoLocker<spinlock, InterruptsSpinLocking> InterruptsSpinLocker;
|
||||
|
||||
|
||||
class ReadSpinLocking {
|
||||
public:
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
acquire_read_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_read_spinlock(lockable);
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, ReadSpinLocking> ReadSpinLocker;
|
||||
|
||||
|
||||
class InterruptsReadSpinLocking {
|
||||
public:
|
||||
InterruptsReadSpinLocking()
|
||||
:
|
||||
fState(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
fState = disable_interrupts();
|
||||
acquire_read_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_read_spinlock(lockable);
|
||||
restore_interrupts(fState);
|
||||
}
|
||||
|
||||
private:
|
||||
int fState;
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, InterruptsReadSpinLocking>
|
||||
InterruptsReadSpinLocker;
|
||||
|
||||
|
||||
class WriteSpinLocking {
|
||||
public:
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
acquire_write_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_write_spinlock(lockable);
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, WriteSpinLocking> WriteSpinLocker;
|
||||
|
||||
|
||||
class InterruptsWriteSpinLocking {
|
||||
public:
|
||||
InterruptsWriteSpinLocking()
|
||||
:
|
||||
fState(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Lock(rw_spinlock* lockable)
|
||||
{
|
||||
fState = disable_interrupts();
|
||||
acquire_write_spinlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(rw_spinlock* lockable)
|
||||
{
|
||||
release_write_spinlock(lockable);
|
||||
restore_interrupts(fState);
|
||||
}
|
||||
|
||||
private:
|
||||
int fState;
|
||||
};
|
||||
|
||||
typedef AutoLocker<rw_spinlock, InterruptsWriteSpinLocking>
|
||||
InterruptsWriteSpinLocker;
|
||||
|
||||
|
||||
class WriteSequentialLocking {
|
||||
public:
|
||||
inline bool Lock(seqlock* lockable)
|
||||
{
|
||||
acquire_write_seqlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(seqlock* lockable)
|
||||
{
|
||||
release_write_seqlock(lockable);
|
||||
}
|
||||
};
|
||||
|
||||
typedef AutoLocker<seqlock, WriteSequentialLocking> WriteSequentialLocker;
|
||||
|
||||
|
||||
class InterruptsWriteSequentialLocking {
|
||||
public:
|
||||
InterruptsWriteSequentialLocking()
|
||||
:
|
||||
fState(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Lock(seqlock* lockable)
|
||||
{
|
||||
fState = disable_interrupts();
|
||||
acquire_write_seqlock(lockable);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Unlock(seqlock* lockable)
|
||||
{
|
||||
release_write_seqlock(lockable);
|
||||
restore_interrupts(fState);
|
||||
}
|
||||
|
||||
private:
|
||||
int fState;
|
||||
};
|
||||
|
||||
typedef AutoLocker<seqlock, InterruptsWriteSequentialLocking>
|
||||
InterruptsWriteSequentialLocker;
|
||||
|
||||
|
||||
class ThreadCPUPinLocking {
|
||||
public:
|
||||
inline bool Lock(Thread* thread)
|
||||
@ -191,6 +329,12 @@ using BPrivate::WriteLocker;
|
||||
using BPrivate::InterruptsLocker;
|
||||
using BPrivate::SpinLocker;
|
||||
using BPrivate::InterruptsSpinLocker;
|
||||
using BPrivate::ReadSpinLocker;
|
||||
using BPrivate::InterruptsReadSpinLocker;
|
||||
using BPrivate::WriteSpinLocker;
|
||||
using BPrivate::InterruptsWriteSpinLocker;
|
||||
using BPrivate::WriteSequentialLocker;
|
||||
using BPrivate::InterruptsWriteSequentialLocker;
|
||||
using BPrivate::ThreadCPUPinner;
|
||||
using BPrivate::TeamLocker;
|
||||
using BPrivate::ThreadLocker;
|
||||
|
60
headers/private/kernel/util/BitUtils.h
Normal file
60
headers/private/kernel/util/BitUtils.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_BITUTIL_H
|
||||
#define KERNEL_UTIL_BITUTIL_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
static inline uint32
|
||||
next_power_of_2(uint32 v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
static inline uint32
|
||||
count_set_bits(uint32 v)
|
||||
{
|
||||
v = v - ((v >> 1) & 0x55555555);
|
||||
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
|
||||
return (((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
log2(uint32 v)
|
||||
{
|
||||
static const int MultiplyDeBruijnBitPosition[32] = {
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return MultiplyDeBruijnBitPosition[(uint32)(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
|
||||
#endif // KERNEL_UTIL_RANDOM_H
|
||||
|
82
headers/private/kernel/util/Bitmap.h
Normal file
82
headers/private/kernel/util/Bitmap.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_BITMAP_H
|
||||
#define KERNEL_UTIL_BITMAP_H
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class Bitmap {
|
||||
public:
|
||||
Bitmap(int bitCount);
|
||||
~Bitmap();
|
||||
|
||||
inline status_t GetInitStatus();
|
||||
|
||||
inline bool Get(int index) const;
|
||||
inline void Set(int index);
|
||||
inline void Clear(int index);
|
||||
|
||||
int GetHighestSet() const;
|
||||
|
||||
private:
|
||||
status_t fInitStatus;
|
||||
|
||||
int fElementsCount;
|
||||
int fSize;
|
||||
addr_t* fBits;
|
||||
|
||||
static const int kBitsPerElement;
|
||||
};
|
||||
|
||||
|
||||
status_t
|
||||
Bitmap::GetInitStatus()
|
||||
{
|
||||
return fInitStatus;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Bitmap::Get(int index) const
|
||||
{
|
||||
ASSERT(index < fSize);
|
||||
|
||||
const int kArrayElement = index / kBitsPerElement;
|
||||
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
|
||||
return fBits[kArrayElement] & kBitMask;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Bitmap::Set(int index)
|
||||
{
|
||||
ASSERT(index < fSize);
|
||||
|
||||
const int kArrayElement = index / kBitsPerElement;
|
||||
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
|
||||
fBits[kArrayElement] |= kBitMask;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Bitmap::Clear(int index)
|
||||
{
|
||||
ASSERT(index < fSize);
|
||||
|
||||
const int kArrayElement = index / kBitsPerElement;
|
||||
const addr_t kBitMask = addr_t(1) << (index % kBitsPerElement);
|
||||
fBits[kArrayElement] &= ~addr_t(kBitMask);
|
||||
}
|
||||
|
||||
|
||||
#endif // KERNEL_UTIL_BITMAP_H
|
||||
|
357
headers/private/kernel/util/Heap.h
Normal file
357
headers/private/kernel/util/Heap.h
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_HEAP_H
|
||||
#define KERNEL_UTIL_HEAP_H
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
struct HeapLink {
|
||||
HeapLink();
|
||||
|
||||
int fIndex;
|
||||
Key fKey;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key>
|
||||
class HeapLinkImpl {
|
||||
private:
|
||||
typedef HeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* GetHeapLink();
|
||||
|
||||
private:
|
||||
Link fHeapLink;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key>
|
||||
class HeapStandardGetLink {
|
||||
private:
|
||||
typedef HeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* operator()(Element* element) const;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key,
|
||||
HeapLink<Element, Key> Element::*LinkMember>
|
||||
class HeapMemberGetLink {
|
||||
private:
|
||||
typedef HeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* operator()(Element* element) const;
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
class HeapLesserCompare {
|
||||
public:
|
||||
inline bool operator()(Key a, Key b);
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
class HeapGreaterCompare {
|
||||
public:
|
||||
inline bool operator()(Key a, Key b);
|
||||
};
|
||||
|
||||
#define HEAP_TEMPLATE_LIST \
|
||||
template<typename Element, typename Key, typename Compare, typename GetLink>
|
||||
#define HEAP_CLASS_NAME Heap<Element, Key, Compare, GetLink>
|
||||
|
||||
template<typename Element, typename Key,
|
||||
typename Compare = HeapLesserCompare<Key>,
|
||||
typename GetLink = HeapStandardGetLink<Element, Key> >
|
||||
class Heap {
|
||||
public:
|
||||
Heap();
|
||||
Heap(int initialSize);
|
||||
~Heap();
|
||||
|
||||
inline Element* PeekRoot() const;
|
||||
|
||||
static const Key& GetKey(Element* element);
|
||||
|
||||
inline void ModifyKey(Element* element, Key newKey);
|
||||
|
||||
inline void RemoveRoot();
|
||||
inline status_t Insert(Element* element, Key key);
|
||||
|
||||
private:
|
||||
status_t _GrowHeap(int minimalSize = 0);
|
||||
|
||||
void _MoveUp(HeapLink<Element, Key>* link);
|
||||
void _MoveDown(HeapLink<Element, Key>* link);
|
||||
|
||||
Element** fElements;
|
||||
int fLastElement;
|
||||
int fSize;
|
||||
|
||||
static Compare sCompare;
|
||||
static GetLink sGetLink;
|
||||
};
|
||||
|
||||
|
||||
#if KDEBUG
|
||||
template<typename Element, typename Key>
|
||||
HeapLink<Element, Key>::HeapLink()
|
||||
:
|
||||
fIndex(-1)
|
||||
{
|
||||
}
|
||||
#else
|
||||
template<typename Element, typename Key>
|
||||
HeapLink<Element, Key>::HeapLink()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
HeapLink<Element, Key>*
|
||||
HeapLinkImpl<Element, Key>::GetHeapLink()
|
||||
{
|
||||
return &fHeapLink;
|
||||
}
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
HeapLink<Element, Key>*
|
||||
HeapStandardGetLink<Element, Key>::operator()(Element* element) const
|
||||
{
|
||||
return element->GetHeapLink();
|
||||
}
|
||||
|
||||
|
||||
template<typename Element, typename Key,
|
||||
HeapLink<Element, Key> Element::*LinkMember>
|
||||
HeapLink<Element, Key>*
|
||||
HeapMemberGetLink<Element, Key, LinkMember>::operator()(Element* element) const
|
||||
{
|
||||
return &(element->*LinkMember);
|
||||
}
|
||||
|
||||
|
||||
template<typename Key>
|
||||
bool
|
||||
HeapLesserCompare<Key>::operator()(Key a, Key b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
|
||||
template<typename Key>
|
||||
bool
|
||||
HeapGreaterCompare<Key>::operator()(Key a, Key b)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
HEAP_CLASS_NAME::Heap()
|
||||
:
|
||||
fElements(NULL),
|
||||
fLastElement(0),
|
||||
fSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
HEAP_CLASS_NAME::Heap(int initialSize)
|
||||
:
|
||||
fElements(NULL),
|
||||
fLastElement(0),
|
||||
fSize(0)
|
||||
{
|
||||
_GrowHeap(initialSize);
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
HEAP_CLASS_NAME::~Heap()
|
||||
{
|
||||
free(fElements);
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
Element*
|
||||
HEAP_CLASS_NAME::PeekRoot() const
|
||||
{
|
||||
if (fLastElement > 0)
|
||||
return fElements[0];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
const Key&
|
||||
HEAP_CLASS_NAME::GetKey(Element* element)
|
||||
{
|
||||
return sGetLink(element)->fKey;
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
void
|
||||
HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
|
||||
{
|
||||
HeapLink<Element, Key>* link = sGetLink(element);
|
||||
|
||||
ASSERT(link->fIndex >= 0 && link->fIndex < fLastElement);
|
||||
Key oldKey = link->fKey;
|
||||
link->fKey = newKey;
|
||||
|
||||
if (sCompare(newKey, oldKey))
|
||||
_MoveUp(link);
|
||||
else if (sCompare(oldKey, newKey))
|
||||
_MoveDown(link);
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
void
|
||||
HEAP_CLASS_NAME::RemoveRoot()
|
||||
{
|
||||
ASSERT(fLastElement > 0);
|
||||
|
||||
#if KDEBUG
|
||||
Element* element = PeekRoot();
|
||||
HeapLink<Element, Key>* link = sGetLink(element);
|
||||
ASSERT(link->fIndex != -1);
|
||||
link->fIndex = -1;
|
||||
#endif
|
||||
|
||||
fLastElement--;
|
||||
if (fLastElement > 0) {
|
||||
Element* lastElement = fElements[fLastElement];
|
||||
fElements[0] = lastElement;
|
||||
sGetLink(lastElement)->fIndex = 0;
|
||||
_MoveDown(sGetLink(lastElement));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
status_t
|
||||
HEAP_CLASS_NAME::Insert(Element* element, Key key)
|
||||
{
|
||||
if (fLastElement == fSize) {
|
||||
status_t result = _GrowHeap();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
}
|
||||
|
||||
ASSERT(fLastElement != fSize);
|
||||
|
||||
HeapLink<Element, Key>* link = sGetLink(element);
|
||||
|
||||
ASSERT(link->fIndex == -1);
|
||||
|
||||
fElements[fLastElement] = element;
|
||||
link->fIndex = fLastElement++;
|
||||
link->fKey = key;
|
||||
_MoveUp(link);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
status_t
|
||||
HEAP_CLASS_NAME::_GrowHeap(int minimalSize)
|
||||
{
|
||||
int newSize = max_c(max_c(fSize * 2, 4), minimalSize);
|
||||
|
||||
size_t arraySize = newSize * sizeof(Element*);
|
||||
Element** newBuffer
|
||||
= reinterpret_cast<Element**>(realloc(fElements, arraySize));
|
||||
if (newBuffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fElements = newBuffer;
|
||||
fSize = newSize;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
void
|
||||
HEAP_CLASS_NAME::_MoveUp(HeapLink<Element, Key>* link)
|
||||
{
|
||||
while (true) {
|
||||
int parent = (link->fIndex - 1) / 2;
|
||||
if (link->fIndex > 0
|
||||
&& sCompare(link->fKey, sGetLink(fElements[parent])->fKey)) {
|
||||
|
||||
sGetLink(fElements[parent])->fIndex = link->fIndex;
|
||||
|
||||
Element* element = fElements[link->fIndex];
|
||||
fElements[link->fIndex] = fElements[parent];
|
||||
fElements[parent] = element;
|
||||
|
||||
link->fIndex = parent;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
void
|
||||
HEAP_CLASS_NAME::_MoveDown(HeapLink<Element, Key>* link)
|
||||
{
|
||||
int current;
|
||||
|
||||
while (true) {
|
||||
current = link->fIndex;
|
||||
|
||||
int child = 2 * link->fIndex + 1;
|
||||
if (child < fLastElement
|
||||
&& sCompare(sGetLink(fElements[child])->fKey, link->fKey)) {
|
||||
current = child;
|
||||
}
|
||||
|
||||
child = 2 * link->fIndex + 2;
|
||||
if (child < fLastElement
|
||||
&& sCompare(sGetLink(fElements[child])->fKey,
|
||||
sGetLink(fElements[current])->fKey)) {
|
||||
current = child;
|
||||
}
|
||||
|
||||
if (link->fIndex == current)
|
||||
break;
|
||||
|
||||
sGetLink(fElements[current])->fIndex = link->fIndex;
|
||||
|
||||
Element* element = fElements[link->fIndex];
|
||||
fElements[link->fIndex] = fElements[current];
|
||||
fElements[current] = element;
|
||||
|
||||
link->fIndex = current;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
Compare HEAP_CLASS_NAME::sCompare;
|
||||
|
||||
HEAP_TEMPLATE_LIST
|
||||
GetLink HEAP_CLASS_NAME::sGetLink;
|
||||
|
||||
|
||||
#endif // KERNEL_UTIL_HEAP_H
|
||||
|
503
headers/private/kernel/util/MinMaxHeap.h
Normal file
503
headers/private/kernel/util/MinMaxHeap.h
Normal file
@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright 2013 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef KERNEL_UTIL_MIN_MAX_HEAP_H
|
||||
#define KERNEL_UTIL_MIN_MAX_HEAP_H
|
||||
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
struct MinMaxHeapLink {
|
||||
MinMaxHeapLink();
|
||||
|
||||
bool fMinTree;
|
||||
int fIndex;
|
||||
Key fKey;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key>
|
||||
class MinMaxHeapLinkImpl {
|
||||
private:
|
||||
typedef MinMaxHeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* GetMinMaxHeapLink();
|
||||
|
||||
private:
|
||||
Link fMinMaxHeapLink;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key>
|
||||
class MinMaxHeapStandardGetLink {
|
||||
private:
|
||||
typedef MinMaxHeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* operator()(Element* element) const;
|
||||
};
|
||||
|
||||
template<typename Element, typename Key,
|
||||
MinMaxHeapLink<Element, Key> Element::*LinkMember>
|
||||
class MinMaxHeapMemberGetLink {
|
||||
private:
|
||||
typedef MinMaxHeapLink<Element, Key> Link;
|
||||
|
||||
public:
|
||||
inline Link* operator()(Element* element) const;
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
class MinMaxHeapCompare {
|
||||
public:
|
||||
inline bool operator()(Key a, Key b);
|
||||
};
|
||||
|
||||
#define MIN_MAX_HEAP_TEMPLATE_LIST \
|
||||
template<typename Element, typename Key, typename Compare, typename GetLink>
|
||||
#define MIN_MAX_HEAP_CLASS_NAME MinMaxHeap<Element, Key, Compare, GetLink>
|
||||
|
||||
template<typename Element, typename Key,
|
||||
typename Compare = MinMaxHeapCompare<Key>,
|
||||
typename GetLink = MinMaxHeapStandardGetLink<Element, Key> >
|
||||
class MinMaxHeap {
|
||||
public:
|
||||
MinMaxHeap();
|
||||
MinMaxHeap(int initialSize);
|
||||
~MinMaxHeap();
|
||||
|
||||
inline Element* PeekMinimum() const;
|
||||
inline Element* PeekMaximum() const;
|
||||
|
||||
static const Key& GetKey(Element* element);
|
||||
|
||||
inline void ModifyKey(Element* element, Key newKey);
|
||||
|
||||
inline void RemoveMinimum();
|
||||
inline void RemoveMaximum();
|
||||
|
||||
inline status_t Insert(Element* element, Key key);
|
||||
|
||||
private:
|
||||
status_t _GrowHeap(int minimalSize = 0);
|
||||
|
||||
void _MoveUp(MinMaxHeapLink<Element, Key>* link);
|
||||
void _MoveDown(MinMaxHeapLink<Element, Key>* link);
|
||||
bool _ChangeTree(MinMaxHeapLink<Element, Key>* link);
|
||||
|
||||
void _RemoveLast(bool minTree);
|
||||
|
||||
Element** fMinElements;
|
||||
int fMinLastElement;
|
||||
|
||||
Element** fMaxElements;
|
||||
int fMaxLastElement;
|
||||
|
||||
int fSize;
|
||||
|
||||
static Compare sCompare;
|
||||
static GetLink sGetLink;
|
||||
};
|
||||
|
||||
|
||||
#if KDEBUG
|
||||
template<typename Element, typename Key>
|
||||
MinMaxHeapLink<Element, Key>::MinMaxHeapLink()
|
||||
:
|
||||
fIndex(-1)
|
||||
{
|
||||
}
|
||||
#else
|
||||
template<typename Element, typename Key>
|
||||
MinMaxHeapLink<Element, Key>::MinMaxHeapLink()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
MinMaxHeapLink<Element, Key>*
|
||||
MinMaxHeapLinkImpl<Element, Key>::GetMinMaxHeapLink()
|
||||
{
|
||||
return &fMinMaxHeapLink;
|
||||
}
|
||||
|
||||
|
||||
template<typename Element, typename Key>
|
||||
MinMaxHeapLink<Element, Key>*
|
||||
MinMaxHeapStandardGetLink<Element, Key>::operator()(Element* element) const
|
||||
{
|
||||
return element->GetMinMaxHeapLink();
|
||||
}
|
||||
|
||||
|
||||
template<typename Element, typename Key,
|
||||
MinMaxHeapLink<Element, Key> Element::*LinkMember>
|
||||
MinMaxHeapLink<Element, Key>*
|
||||
MinMaxHeapMemberGetLink<Element, Key, LinkMember>::operator()(
|
||||
Element* element) const
|
||||
{
|
||||
return &(element->*LinkMember);
|
||||
}
|
||||
|
||||
|
||||
template<typename Key>
|
||||
bool
|
||||
MinMaxHeapCompare<Key>::operator()(Key a, Key b)
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
MIN_MAX_HEAP_CLASS_NAME::MinMaxHeap()
|
||||
:
|
||||
fMinElements(NULL),
|
||||
fMinLastElement(0),
|
||||
fMaxElements(NULL),
|
||||
fMaxLastElement(0),
|
||||
fSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
MIN_MAX_HEAP_CLASS_NAME::MinMaxHeap(int initialSize)
|
||||
:
|
||||
fMinElements(NULL),
|
||||
fMinLastElement(0),
|
||||
fMaxElements(NULL),
|
||||
fMaxLastElement(0),
|
||||
fSize(0)
|
||||
{
|
||||
_GrowHeap(initialSize);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
MIN_MAX_HEAP_CLASS_NAME::~MinMaxHeap()
|
||||
{
|
||||
free(fMinElements);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
Element*
|
||||
MIN_MAX_HEAP_CLASS_NAME::PeekMinimum() const
|
||||
{
|
||||
if (fMinLastElement > 0)
|
||||
return fMinElements[0];
|
||||
else if (fMaxLastElement > 0) {
|
||||
ASSERT(fMaxLastElement == 1);
|
||||
return fMaxElements[0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
Element*
|
||||
MIN_MAX_HEAP_CLASS_NAME::PeekMaximum() const
|
||||
{
|
||||
if (fMaxLastElement > 0)
|
||||
return fMaxElements[0];
|
||||
else if (fMinLastElement > 0) {
|
||||
ASSERT(fMinLastElement == 1);
|
||||
return fMinElements[0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
const Key&
|
||||
MIN_MAX_HEAP_CLASS_NAME::GetKey(Element* element)
|
||||
{
|
||||
return sGetLink(element)->fKey;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::ModifyKey(Element* element, Key newKey)
|
||||
{
|
||||
MinMaxHeapLink<Element, Key>* link = sGetLink(element);
|
||||
|
||||
Key oldKey = link->fKey;
|
||||
link->fKey = newKey;
|
||||
|
||||
if (!sCompare(newKey, oldKey) && !sCompare(oldKey, newKey))
|
||||
return;
|
||||
|
||||
if (sCompare(newKey, oldKey) ^ !link->fMinTree)
|
||||
_MoveUp(link);
|
||||
else
|
||||
_MoveDown(link);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::RemoveMinimum()
|
||||
{
|
||||
if (fMinLastElement == 0) {
|
||||
ASSERT(fMaxLastElement == 1);
|
||||
RemoveMaximum();
|
||||
return;
|
||||
}
|
||||
|
||||
#if KDEBUG
|
||||
Element* element = PeekMinimum();
|
||||
MinMaxHeapLink<Element, Key>* link = sGetLink(element);
|
||||
ASSERT(link->fIndex != -1);
|
||||
link->fIndex = -1;
|
||||
#endif
|
||||
|
||||
_RemoveLast(true);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::RemoveMaximum()
|
||||
{
|
||||
if (fMaxLastElement == 0) {
|
||||
ASSERT(fMinLastElement == 1);
|
||||
RemoveMinimum();
|
||||
return;
|
||||
}
|
||||
|
||||
#if KDEBUG
|
||||
Element* element = PeekMaximum();
|
||||
MinMaxHeapLink<Element, Key>* link = sGetLink(element);
|
||||
ASSERT(link->fIndex != -1);
|
||||
link->fIndex = -1;
|
||||
#endif
|
||||
|
||||
_RemoveLast(false);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
status_t
|
||||
MIN_MAX_HEAP_CLASS_NAME::Insert(Element* element, Key key)
|
||||
{
|
||||
if (min_c(fMinLastElement, fMaxLastElement) == fSize) {
|
||||
ASSERT(max_c(fMinLastElement, fMaxLastElement) == fSize);
|
||||
status_t result = _GrowHeap();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
}
|
||||
|
||||
ASSERT(fMinLastElement < fSize || fMaxLastElement < fSize);
|
||||
|
||||
MinMaxHeapLink<Element, Key>* link = sGetLink(element);
|
||||
|
||||
ASSERT(link->fIndex == -1);
|
||||
|
||||
link->fMinTree = fMinLastElement < fMaxLastElement;
|
||||
|
||||
int& lastElement = link->fMinTree ? fMinLastElement : fMaxLastElement;
|
||||
Element** tree = link->fMinTree ? fMinElements : fMaxElements;
|
||||
|
||||
tree[lastElement] = element;
|
||||
link->fIndex = lastElement++;
|
||||
link->fKey = key;
|
||||
|
||||
if (!_ChangeTree(link))
|
||||
_MoveUp(link);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
status_t
|
||||
MIN_MAX_HEAP_CLASS_NAME::_GrowHeap(int minimalSize)
|
||||
{
|
||||
minimalSize = minimalSize % 2 == 0 ? minimalSize : minimalSize + 1;
|
||||
int newSize = max_c(max_c(fSize * 4, 4), minimalSize);
|
||||
|
||||
size_t arraySize = newSize * sizeof(Element*);
|
||||
Element** newBuffer
|
||||
= reinterpret_cast<Element**>(realloc(fMinElements, arraySize));
|
||||
if (newBuffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
fMinElements = newBuffer;
|
||||
|
||||
newBuffer += newSize / 2;
|
||||
if (fMaxLastElement > 0)
|
||||
memcpy(newBuffer, fMinElements + fSize, fSize * sizeof(Element*));
|
||||
fMaxElements = newBuffer;
|
||||
|
||||
fSize = newSize / 2;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::_MoveUp(MinMaxHeapLink<Element, Key>* link)
|
||||
{
|
||||
Element** tree = link->fMinTree ? fMinElements : fMaxElements;
|
||||
while (true) {
|
||||
if (link->fIndex <= 0)
|
||||
break;
|
||||
|
||||
int parent = (link->fIndex - 1) / 2;
|
||||
bool isSmaller = sCompare(link->fKey, sGetLink(tree[parent])->fKey);
|
||||
if (isSmaller ^ !link->fMinTree) {
|
||||
ASSERT(sGetLink(tree[parent])->fIndex == parent);
|
||||
sGetLink(tree[parent])->fIndex = link->fIndex;
|
||||
|
||||
Element* element = tree[link->fIndex];
|
||||
tree[link->fIndex] = tree[parent];
|
||||
tree[parent] = element;
|
||||
|
||||
link->fIndex = parent;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::_MoveDown(MinMaxHeapLink<Element, Key>* link)
|
||||
{
|
||||
int current;
|
||||
|
||||
int lastElement = link->fMinTree ? fMinLastElement : fMaxLastElement;
|
||||
Element** tree = link->fMinTree ? fMinElements : fMaxElements;
|
||||
while (true) {
|
||||
current = link->fIndex;
|
||||
|
||||
int child = 2 * link->fIndex + 1;
|
||||
if (child < lastElement) {
|
||||
bool isSmaller = sCompare(sGetLink(tree[child])->fKey, link->fKey);
|
||||
if (isSmaller ^ !link->fMinTree)
|
||||
current = child;
|
||||
}
|
||||
|
||||
child = 2 * link->fIndex + 2;
|
||||
if (child < lastElement) {
|
||||
bool isSmaller = sCompare(sGetLink(tree[child])->fKey,
|
||||
sGetLink(tree[current])->fKey);
|
||||
if (isSmaller ^ !link->fMinTree)
|
||||
current = child;
|
||||
}
|
||||
|
||||
if (link->fIndex == current)
|
||||
break;
|
||||
|
||||
ASSERT(sGetLink(tree[current])->fIndex == current);
|
||||
sGetLink(tree[current])->fIndex = link->fIndex;
|
||||
|
||||
Element* element = tree[link->fIndex];
|
||||
tree[link->fIndex] = tree[current];
|
||||
tree[current] = element;
|
||||
|
||||
link->fIndex = current;
|
||||
}
|
||||
|
||||
if (2 * link->fIndex + 1 >= lastElement)
|
||||
_ChangeTree(link);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
bool
|
||||
MIN_MAX_HEAP_CLASS_NAME::_ChangeTree(MinMaxHeapLink<Element, Key>* link)
|
||||
{
|
||||
int otherLastElement = link->fMinTree ? fMaxLastElement : fMinLastElement;
|
||||
|
||||
Element** currentTree = link->fMinTree ? fMinElements : fMaxElements;
|
||||
Element** otherTree = link->fMinTree ? fMaxElements : fMinElements;
|
||||
|
||||
if (otherLastElement <= 0) {
|
||||
ASSERT(link->fMinTree ? fMinLastElement : fMaxLastElement == 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERT((link->fIndex - 1) / 2 < otherLastElement);
|
||||
|
||||
Element* predecessor;
|
||||
if (2 * link->fIndex + 1 < otherLastElement) {
|
||||
predecessor = otherTree[2 * link->fIndex + 1];
|
||||
ASSERT(sGetLink(predecessor)->fIndex == 2 * link->fIndex + 1);
|
||||
} else if (link->fIndex < otherLastElement) {
|
||||
predecessor = otherTree[link->fIndex];
|
||||
ASSERT(sGetLink(predecessor)->fIndex == link->fIndex);
|
||||
} else {
|
||||
predecessor = otherTree[(link->fIndex - 1) / 2];
|
||||
ASSERT(sGetLink(predecessor)->fIndex == (link->fIndex - 1) / 2);
|
||||
}
|
||||
MinMaxHeapLink<Element, Key>* predecessorLink = sGetLink(predecessor);
|
||||
|
||||
bool isSmaller = sCompare(predecessorLink->fKey, link->fKey);
|
||||
if (isSmaller ^ !link->fMinTree) {
|
||||
Element* element = currentTree[link->fIndex];
|
||||
currentTree[link->fIndex] = otherTree[predecessorLink->fIndex];
|
||||
otherTree[predecessorLink->fIndex] = element;
|
||||
|
||||
int index = link->fIndex;
|
||||
link->fIndex = predecessorLink->fIndex;
|
||||
predecessorLink->fIndex = index;
|
||||
|
||||
predecessorLink->fMinTree = !predecessorLink->fMinTree;
|
||||
link->fMinTree = !link->fMinTree;
|
||||
|
||||
_MoveUp(link);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
void
|
||||
MIN_MAX_HEAP_CLASS_NAME::_RemoveLast(bool minTree)
|
||||
{
|
||||
bool deleteMin = fMaxLastElement < fMinLastElement;
|
||||
|
||||
Element** tree = deleteMin ? fMinElements : fMaxElements;
|
||||
int& lastElement = deleteMin ? fMinLastElement : fMaxLastElement;
|
||||
|
||||
ASSERT(lastElement > 0);
|
||||
lastElement--;
|
||||
if (lastElement == 0 && deleteMin == minTree)
|
||||
return;
|
||||
|
||||
Element* element = tree[lastElement];
|
||||
|
||||
if (minTree)
|
||||
fMinElements[0] = element;
|
||||
else
|
||||
fMaxElements[0] = element;
|
||||
|
||||
MinMaxHeapLink<Element, Key>* link = sGetLink(element);
|
||||
link->fIndex = 0;
|
||||
link->fMinTree = minTree;
|
||||
_MoveDown(link);
|
||||
}
|
||||
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
Compare MIN_MAX_HEAP_CLASS_NAME::sCompare;
|
||||
|
||||
MIN_MAX_HEAP_TEMPLATE_LIST
|
||||
GetLink MIN_MAX_HEAP_CLASS_NAME::sGetLink;
|
||||
|
||||
|
||||
#endif // KERNEL_UTIL_MIN_MAX_HEAP_H
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -18,22 +20,34 @@ atomic_pointer_test_and_set(PointerType** _pointer, const PointerType* set,
|
||||
const PointerType* test)
|
||||
{
|
||||
#if LONG_MAX == INT_MAX
|
||||
return (PointerType*)atomic_test_and_set((vint32*)_pointer, (int32)set,
|
||||
return (PointerType*)atomic_test_and_set((int32*)_pointer, (int32)set,
|
||||
(int32)test);
|
||||
#else
|
||||
return (PointerType*)atomic_test_and_set64((vint64*)_pointer, (int64)set,
|
||||
return (PointerType*)atomic_test_and_set64((int64*)_pointer, (int64)set,
|
||||
(int64)test);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template<typename PointerType> PointerType*
|
||||
atomic_pointer_set(PointerType** _pointer, const PointerType* set)
|
||||
atomic_pointer_get_and_set(PointerType** _pointer, const PointerType* set)
|
||||
{
|
||||
#if LONG_MAX == INT_MAX
|
||||
return (PointerType*)atomic_set((vint32*)_pointer, (int32)set);
|
||||
return (PointerType*)atomic_get_and_set((int32*)_pointer, (int32)set);
|
||||
#else
|
||||
return (PointerType*)atomic_set64((vint64*)_pointer, (int64)set);
|
||||
return (PointerType*)atomic_get_and_set64((int64*)_pointer, (int64)set);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
template<typename PointerType> void
|
||||
atomic_pointer_set(PointerType** _pointer, const PointerType* set)
|
||||
{
|
||||
ASSERT((addr_t(_pointer) & (sizeof(PointerType*) - 1)) == 0);
|
||||
#if LONG_MAX == INT_MAX
|
||||
atomic_set((int32*)_pointer, (int32)set);
|
||||
#else
|
||||
atomic_set64((int64*)_pointer, (int64)set);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -41,10 +55,11 @@ atomic_pointer_set(PointerType** _pointer, const PointerType* set)
|
||||
template<typename PointerType> PointerType*
|
||||
atomic_pointer_get(PointerType** _pointer)
|
||||
{
|
||||
ASSERT((addr_t(_pointer) & (sizeof(PointerType*) - 1)) == 0);
|
||||
#if LONG_MAX == INT_MAX
|
||||
return (PointerType*)atomic_get((vint32*)_pointer);
|
||||
return (PointerType*)atomic_get((int32*)_pointer);
|
||||
#else
|
||||
return (PointerType*)atomic_get64((vint64*)_pointer);
|
||||
return (PointerType*)atomic_get64((int64*)_pointer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ status_t vm_get_physical_page_debug(phys_addr_t paddr, addr_t* vaddr,
|
||||
void** _handle);
|
||||
status_t vm_put_physical_page_debug(addr_t vaddr, void* handle);
|
||||
|
||||
void vm_get_info(struct system_memory_info *info);
|
||||
void vm_get_info(system_info *info);
|
||||
uint32 vm_num_page_faults(void);
|
||||
off_t vm_available_memory(void);
|
||||
off_t vm_available_not_needed_memory(void);
|
||||
|
@ -136,7 +136,7 @@ public:
|
||||
#endif
|
||||
|
||||
#if DEBUG_PAGE_ACCESS
|
||||
vint32 accessing_thread;
|
||||
int32 accessing_thread;
|
||||
#endif
|
||||
|
||||
#if VM_PAGE_ALLOCATION_TRACKING_AVAILABLE
|
||||
|
@ -17,12 +17,12 @@ struct select_sync;
|
||||
typedef struct select_info {
|
||||
struct select_info* next; // next in the object's list
|
||||
struct select_sync* sync;
|
||||
vint32 events;
|
||||
int32 events;
|
||||
uint16 selected_events;
|
||||
} select_info;
|
||||
|
||||
typedef struct select_sync {
|
||||
vint32 ref_count;
|
||||
int32 ref_count;
|
||||
sem_id sem;
|
||||
uint32 count;
|
||||
struct select_info* set;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user