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:
Pawel Dziepak 2014-01-17 04:06:15 +01:00
commit d0f2d8282f
356 changed files with 11797 additions and 9927 deletions

View File

@ -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

View File

@ -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

View File

@ -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 ;

View File

@ -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 ;

View File

@ -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 Частата Працэсара

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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 सीपियु की आवृत्ति

View File

@ -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

View File

@ -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

View File

@ -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à:

View File

@ -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 周波数

View File

@ -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 스테핑 정책:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 Частота процессора

View File

@ -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

View File

@ -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

View File

@ -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 Частота процесора

View File

@ -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 2009Haiku .Inc。\n
CPUFrequency System name CPU 监视器

View File

@ -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 2009Haiku .Inc。\n
CPUFrequency System name CPU 监视器

View File

@ -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()

View File

@ -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);

View File

@ -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 (); }

View File

@ -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,

View 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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -14,7 +14,7 @@
typedef struct lock {
sem_id sem;
vint32 count;
int32 count;
} lock;

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -92,7 +92,7 @@ private:
private:
ThreadCreationAttributes fCreationAttributes;
char fThreadName[B_OS_NAME_LENGTH];
bool fPendingDPC;
int32 fPendingDPC;
};

View File

@ -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;
};

View 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

View File

@ -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 */

View File

@ -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
}

View File

@ -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 */

View File

@ -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
}

View 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

View File

@ -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 */

View File

@ -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)

View 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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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>

View 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

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View 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

View 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

View 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

View 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

View File

@ -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
}

View File

@ -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);

View File

@ -136,7 +136,7 @@ public:
#endif
#if DEBUG_PAGE_ACCESS
vint32 accessing_thread;
int32 accessing_thread;
#endif
#if VM_PAGE_ALLOCATION_TRACKING_AVAILABLE

View File

@ -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